Skip to content

Commit f77ead0

Browse files
committed
Auto merge of rust-lang#135835 - matthiaskrgr:rollup-pzaa7cn, r=matthiaskrgr
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
2 parents cd805f0 + 1e3f266 commit f77ead0

35 files changed

+322
-134
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ __pycache__/
8383
node_modules
8484
package-lock.json
8585
package.json
86+
/src/doc/rustc-dev-guide/mermaid.min.js
8687

8788
## Rustdoc GUI tests
8889
tests/rustdoc-gui/src/**.lock

compiler/rustc_borrowck/src/type_check/canonical.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
185185
CustomTypeOp::new(
186186
|ocx| {
187187
let structurally_normalize = |ty| {
188-
ocx.structurally_normalize(
188+
ocx.structurally_normalize_ty(
189189
&ObligationCause::misc(
190190
location.to_locations().span(body),
191191
body.source.def_id().expect_local(),
@@ -230,7 +230,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
230230
ConstraintCategory::Boring,
231231
CustomTypeOp::new(
232232
|ocx| {
233-
ocx.structurally_normalize(
233+
ocx.structurally_normalize_ty(
234234
&ObligationCause::misc(
235235
location.to_locations().span(body),
236236
body.source.def_id().expect_local(),

compiler/rustc_hir_analysis/src/autoderef.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
8686
if self.infcx.next_trait_solver()
8787
&& let ty::Alias(..) = ty.kind()
8888
{
89-
let (normalized_ty, obligations) = self.structurally_normalize(ty)?;
89+
let (normalized_ty, obligations) = self.structurally_normalize_ty(ty)?;
9090
self.state.obligations.extend(obligations);
9191
(AutoderefKind::Builtin, normalized_ty)
9292
} else {
@@ -166,20 +166,20 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
166166
}
167167

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

173173
Some(self.infcx.resolve_vars_if_possible(normalized_ty))
174174
}
175175

176176
#[instrument(level = "debug", skip(self), ret)]
177-
pub fn structurally_normalize(
177+
pub fn structurally_normalize_ty(
178178
&self,
179179
ty: Ty<'tcx>,
180180
) -> Option<(Ty<'tcx>, PredicateObligations<'tcx>)> {
181181
let ocx = ObligationCtxt::new(self.infcx);
182-
let Ok(normalized_ty) = ocx.structurally_normalize(
182+
let Ok(normalized_ty) = ocx.structurally_normalize_ty(
183183
&traits::ObligationCause::misc(self.span, self.body_id),
184184
self.param_env,
185185
ty,

compiler/rustc_hir_analysis/src/coherence/orphan.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ fn orphan_check<'tcx>(
320320
}
321321

322322
let ty = if infcx.next_trait_solver() {
323-
ocx.structurally_normalize(
323+
ocx.structurally_normalize_ty(
324324
&cause,
325325
ty::ParamEnv::empty(),
326326
infcx.resolve_vars_if_possible(ty),

compiler/rustc_hir_typeck/src/coercion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11241124
if self.next_trait_solver()
11251125
&& let ty::Alias(..) = ty.kind()
11261126
{
1127-
ocx.structurally_normalize(&cause, self.param_env, ty)
1127+
ocx.structurally_normalize_ty(&cause, self.param_env, ty)
11281128
} else {
11291129
Ok(ty)
11301130
}

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1433,7 +1433,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14331433
// in a reentrant borrow, causing an ICE.
14341434
let result = self
14351435
.at(&self.misc(sp), self.param_env)
1436-
.structurally_normalize(ty, &mut **self.fulfillment_cx.borrow_mut());
1436+
.structurally_normalize_ty(ty, &mut **self.fulfillment_cx.borrow_mut());
14371437
match result {
14381438
Ok(normalized_ty) => normalized_ty,
14391439
Err(errors) => {

compiler/rustc_next_trait_solver/src/solve/mod.rs

+19-23
Original file line numberDiff line numberDiff line change
@@ -277,23 +277,7 @@ where
277277
param_env: I::ParamEnv,
278278
ty: I::Ty,
279279
) -> Result<I::Ty, NoSolution> {
280-
if let ty::Alias(..) = ty.kind() {
281-
let normalized_ty = self.next_ty_infer();
282-
let alias_relate_goal = Goal::new(
283-
self.cx(),
284-
param_env,
285-
ty::PredicateKind::AliasRelate(
286-
ty.into(),
287-
normalized_ty.into(),
288-
ty::AliasRelationDirection::Equate,
289-
),
290-
);
291-
self.add_goal(GoalSource::Misc, alias_relate_goal);
292-
self.try_evaluate_added_goals()?;
293-
Ok(self.resolve_vars_if_possible(normalized_ty))
294-
} else {
295-
Ok(ty)
296-
}
280+
self.structurally_normalize_term(param_env, ty.into()).map(|term| term.expect_ty())
297281
}
298282

299283
/// Normalize a const for when it is structurally matched on, or more likely
@@ -308,22 +292,34 @@ where
308292
param_env: I::ParamEnv,
309293
ct: I::Const,
310294
) -> Result<I::Const, NoSolution> {
311-
if let ty::ConstKind::Unevaluated(..) = ct.kind() {
312-
let normalized_ct = self.next_const_infer();
295+
self.structurally_normalize_term(param_env, ct.into()).map(|term| term.expect_const())
296+
}
297+
298+
/// Normalize a term for when it is structurally matched on.
299+
///
300+
/// This function is necessary in nearly all cases before matching on a ty/const.
301+
/// Not doing so is likely to be incomplete and therefore unsound during coherence.
302+
fn structurally_normalize_term(
303+
&mut self,
304+
param_env: I::ParamEnv,
305+
term: I::Term,
306+
) -> Result<I::Term, NoSolution> {
307+
if let Some(_) = term.to_alias_term() {
308+
let normalized_term = self.next_term_infer_of_kind(term);
313309
let alias_relate_goal = Goal::new(
314310
self.cx(),
315311
param_env,
316312
ty::PredicateKind::AliasRelate(
317-
ct.into(),
318-
normalized_ct.into(),
313+
term,
314+
normalized_term,
319315
ty::AliasRelationDirection::Equate,
320316
),
321317
);
322318
self.add_goal(GoalSource::Misc, alias_relate_goal);
323319
self.try_evaluate_added_goals()?;
324-
Ok(self.resolve_vars_if_possible(normalized_ct))
320+
Ok(self.resolve_vars_if_possible(normalized_term))
325321
} else {
326-
Ok(ct)
322+
Ok(term)
327323
}
328324
}
329325

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -1338,20 +1338,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
13381338
let derive_better_type_error =
13391339
|alias_term: ty::AliasTerm<'tcx>, expected_term: ty::Term<'tcx>| {
13401340
let ocx = ObligationCtxt::new(self);
1341-
let normalized_term = match expected_term.unpack() {
1342-
ty::TermKind::Ty(_) => self.next_ty_var(DUMMY_SP).into(),
1343-
ty::TermKind::Const(_) => self.next_const_var(DUMMY_SP).into(),
1344-
};
1345-
ocx.register_obligation(Obligation::new(
1346-
self.tcx,
1347-
ObligationCause::dummy(),
1341+
1342+
let Ok(normalized_term) = ocx.structurally_normalize_term(
1343+
&ObligationCause::dummy(),
13481344
obligation.param_env,
1349-
ty::PredicateKind::NormalizesTo(ty::NormalizesTo {
1350-
alias: alias_term,
1351-
term: normalized_term,
1352-
}),
1353-
));
1354-
let _ = ocx.select_where_possible();
1345+
alias_term.to_term(self.tcx),
1346+
) else {
1347+
return None;
1348+
};
1349+
13551350
if let Err(terr) = ocx.eq(
13561351
&ObligationCause::dummy(),
13571352
obligation.param_env,

compiler/rustc_trait_selection/src/traits/coherence.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
709709
if matches!(ty.kind(), ty::Alias(..)) {
710710
let ocx = ObligationCtxt::new(infcx);
711711
ty = ocx
712-
.structurally_normalize(&ObligationCause::dummy(), param_env, ty)
712+
.structurally_normalize_ty(&ObligationCause::dummy(), param_env, ty)
713713
.map_err(|_| ())?;
714714
if !ocx.select_where_possible().is_empty() {
715715
return Err(());

compiler/rustc_trait_selection/src/traits/engine.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -319,15 +319,15 @@ where
319319
self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
320320
}
321321

322-
pub fn structurally_normalize(
322+
pub fn structurally_normalize_ty(
323323
&self,
324324
cause: &ObligationCause<'tcx>,
325325
param_env: ty::ParamEnv<'tcx>,
326326
value: Ty<'tcx>,
327327
) -> Result<Ty<'tcx>, Vec<E>> {
328328
self.infcx
329329
.at(cause, param_env)
330-
.structurally_normalize(value, &mut **self.engine.borrow_mut())
330+
.structurally_normalize_ty(value, &mut **self.engine.borrow_mut())
331331
}
332332

333333
pub fn structurally_normalize_const(
@@ -340,4 +340,15 @@ where
340340
.at(cause, param_env)
341341
.structurally_normalize_const(value, &mut **self.engine.borrow_mut())
342342
}
343+
344+
pub fn structurally_normalize_term(
345+
&self,
346+
cause: &ObligationCause<'tcx>,
347+
param_env: ty::ParamEnv<'tcx>,
348+
value: ty::Term<'tcx>,
349+
) -> Result<ty::Term<'tcx>, Vec<E>> {
350+
self.infcx
351+
.at(cause, param_env)
352+
.structurally_normalize_term(value, &mut **self.engine.borrow_mut())
353+
}
343354
}

compiler/rustc_trait_selection/src/traits/structural_normalize.rs

+25-48
Original file line numberDiff line numberDiff line change
@@ -7,59 +7,42 @@ use crate::traits::{NormalizeExt, Obligation};
77

88
#[extension(pub trait StructurallyNormalizeExt<'tcx>)]
99
impl<'tcx> At<'_, 'tcx> {
10-
fn structurally_normalize<E: 'tcx>(
10+
fn structurally_normalize_ty<E: 'tcx>(
1111
&self,
1212
ty: Ty<'tcx>,
1313
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
1414
) -> Result<Ty<'tcx>, Vec<E>> {
15-
assert!(!ty.is_ty_var(), "should have resolved vars before calling");
16-
17-
if self.infcx.next_trait_solver() {
18-
let ty::Alias(..) = *ty.kind() else {
19-
return Ok(ty);
20-
};
21-
22-
let new_infer_ty = self.infcx.next_ty_var(self.cause.span);
23-
24-
// We simply emit an `alias-eq` goal here, since that will take care of
25-
// normalizing the LHS of the projection until it is a rigid projection
26-
// (or a not-yet-defined opaque in scope).
27-
let obligation = Obligation::new(
28-
self.infcx.tcx,
29-
self.cause.clone(),
30-
self.param_env,
31-
ty::PredicateKind::AliasRelate(
32-
ty.into(),
33-
new_infer_ty.into(),
34-
ty::AliasRelationDirection::Equate,
35-
),
36-
);
37-
38-
fulfill_cx.register_predicate_obligation(self.infcx, obligation);
39-
let errors = fulfill_cx.select_where_possible(self.infcx);
40-
if !errors.is_empty() {
41-
return Err(errors);
42-
}
43-
44-
Ok(self.infcx.resolve_vars_if_possible(new_infer_ty))
45-
} else {
46-
Ok(self.normalize(ty).into_value_registering_obligations(self.infcx, fulfill_cx))
47-
}
15+
self.structurally_normalize_term(ty.into(), fulfill_cx).map(|term| term.expect_type())
4816
}
4917

5018
fn structurally_normalize_const<E: 'tcx>(
5119
&self,
5220
ct: ty::Const<'tcx>,
5321
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
5422
) -> Result<ty::Const<'tcx>, Vec<E>> {
55-
assert!(!ct.is_ct_infer(), "should have resolved vars before calling");
23+
if self.infcx.tcx.features().generic_const_exprs() {
24+
return Ok(super::evaluate_const(&self.infcx, ct, self.param_env));
25+
}
26+
27+
self.structurally_normalize_term(ct.into(), fulfill_cx).map(|term| term.expect_const())
28+
}
29+
30+
fn structurally_normalize_term<E: 'tcx>(
31+
&self,
32+
term: ty::Term<'tcx>,
33+
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
34+
) -> Result<ty::Term<'tcx>, Vec<E>> {
35+
assert!(!term.is_infer(), "should have resolved vars before calling");
5636

5737
if self.infcx.next_trait_solver() {
58-
let ty::ConstKind::Unevaluated(..) = ct.kind() else {
59-
return Ok(ct);
60-
};
38+
if let None = term.to_alias_term() {
39+
return Ok(term);
40+
}
6141

62-
let new_infer_ct = self.infcx.next_const_var(self.cause.span);
42+
let new_infer = match term.unpack() {
43+
ty::TermKind::Ty(_) => self.infcx.next_ty_var(self.cause.span).into(),
44+
ty::TermKind::Const(_) => self.infcx.next_const_var(self.cause.span).into(),
45+
};
6346

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

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

84-
Ok(self.infcx.resolve_vars_if_possible(new_infer_ct))
85-
} else if self.infcx.tcx.features().generic_const_exprs() {
86-
Ok(super::evaluate_const(&self.infcx, ct, self.param_env))
63+
Ok(self.infcx.resolve_vars_if_possible(new_infer))
8764
} else {
88-
Ok(self.normalize(ct).into_value_registering_obligations(self.infcx, fulfill_cx))
65+
Ok(self.normalize(term).into_value_registering_obligations(self.infcx, fulfill_cx))
8966
}
9067
}
9168
}

library/core/src/macros/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,17 @@ pub macro cfg_match {
313313
/// }
314314
/// }
315315
/// ```
316+
///
317+
/// If desired, it is possible to return expressions through the use of surrounding braces:
318+
///
319+
/// ```
320+
/// #![feature(cfg_match)]
321+
///
322+
/// let _some_string = cfg_match! {{
323+
/// unix => { "With great power comes great electricity bills" },
324+
/// _ => { "Behind every successful diet is an unwatched pizza" },
325+
/// }};
326+
/// ```
316327
#[cfg(not(bootstrap))]
317328
#[unstable(feature = "cfg_match", issue = "115585")]
318329
#[rustc_diagnostic_item = "cfg_match"]

library/core/src/num/uint_macros.rs

+31-2
Original file line numberDiff line numberDiff line change
@@ -2663,8 +2663,8 @@ macro_rules! uint_impl {
26632663
///
26642664
/// Basic usage:
26652665
///
2666-
/// Please note that this example is shared between integer types.
2667-
/// Which explains why `u32` is used here.
2666+
/// Please note that this example is shared between integer types,
2667+
/// which explains why `u32` is used here.
26682668
///
26692669
/// ```
26702670
/// #![feature(bigint_helper_methods)]
@@ -2677,6 +2677,35 @@ macro_rules! uint_impl {
26772677
"(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX));"
26782678
)]
26792679
/// ```
2680+
///
2681+
/// This is the core per-digit operation for "grade school" O(n²) multiplication.
2682+
///
2683+
/// Please note that this example is shared between integer types,
2684+
/// using `u8` for simplicity of the demonstration.
2685+
///
2686+
/// ```
2687+
/// #![feature(bigint_helper_methods)]
2688+
///
2689+
/// fn quadratic_mul<const N: usize>(a: [u8; N], b: [u8; N]) -> [u8; N] {
2690+
/// let mut out = [0; N];
2691+
/// for j in 0..N {
2692+
/// let mut carry = 0;
2693+
/// for i in 0..(N - j) {
2694+
/// (out[j + i], carry) = u8::carrying_mul_add(a[i], b[j], out[j + i], carry);
2695+
/// }
2696+
/// }
2697+
/// out
2698+
/// }
2699+
///
2700+
/// // -1 * -1 == 1
2701+
/// assert_eq!(quadratic_mul([0xFF; 3], [0xFF; 3]), [1, 0, 0]);
2702+
///
2703+
/// assert_eq!(u32::wrapping_mul(0x9e3779b9, 0x7f4a7c15), 0xCFFC982D);
2704+
/// assert_eq!(
2705+
/// quadratic_mul(u32::to_le_bytes(0x9e3779b9), u32::to_le_bytes(0x7f4a7c15)),
2706+
/// u32::to_le_bytes(0xCFFC982D)
2707+
/// );
2708+
/// ```
26802709
#[unstable(feature = "bigint_helper_methods", issue = "85532")]
26812710
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
26822711
#[must_use = "this returns the result of the operation, \

0 commit comments

Comments
 (0)