Auto merge of #102471 - Dylan-DPC:rollup-ij3okjt, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #102336 (Fix associated type bindings with anon const in GAT position) - #102342 (Add negation methods for signed non-zero integers.) - #102385 (Don't export `__heap_base` and `__data_end` on wasm32-wasi.) - #102435 (Improve example of Iterator::reduce) - #102436 (rustdoc: clean up "normalize.css 8" input override CSS) - #102452 (fix minor ungrammatical sentence) - #102455 (Use let-chaining in `WhileTrue::check_expr`.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
65445a571c
9 changed files with 301 additions and 86 deletions
|
@ -1320,10 +1320,12 @@ impl<'a> Linker for WasmLd<'a> {
|
||||||
|
|
||||||
// LLD will hide these otherwise-internal symbols since it only exports
|
// LLD will hide these otherwise-internal symbols since it only exports
|
||||||
// symbols explicitly passed via the `--export` flags above and hides all
|
// symbols explicitly passed via the `--export` flags above and hides all
|
||||||
// others. Various bits and pieces of tooling use this, so be sure these
|
// others. Various bits and pieces of wasm32-unknown-unknown tooling use
|
||||||
// symbols make their way out of the linker as well.
|
// this, so be sure these symbols make their way out of the linker as well.
|
||||||
self.cmd.arg("--export=__heap_base");
|
if self.sess.target.os == "unknown" {
|
||||||
self.cmd.arg("--export=__data_end");
|
self.cmd.arg("--export=__heap_base");
|
||||||
|
self.cmd.arg("--export=__data_end");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subsystem(&mut self, _subsystem: &str) {}
|
fn subsystem(&mut self, _subsystem: &str) {}
|
||||||
|
|
|
@ -333,7 +333,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||||
find_opaque_ty_constraints_for_tait(tcx, def_id)
|
find_opaque_ty_constraints_for_tait(tcx, def_id)
|
||||||
}
|
}
|
||||||
// Opaque types desugared from `impl Trait`.
|
// Opaque types desugared from `impl Trait`.
|
||||||
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), in_trait, .. }) => {
|
ItemKind::OpaqueTy(OpaqueTy {
|
||||||
|
origin:
|
||||||
|
hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner),
|
||||||
|
in_trait,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
if in_trait {
|
if in_trait {
|
||||||
span_bug!(item.span, "impl-trait in trait has no default")
|
span_bug!(item.span, "impl-trait in trait has no default")
|
||||||
} else {
|
} else {
|
||||||
|
@ -378,7 +383,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||||
|
|
||||||
Node::Field(field) => icx.to_ty(field.ty),
|
Node::Field(field) => icx.to_ty(field.ty),
|
||||||
|
|
||||||
Node::Expr(&Expr { kind: ExprKind::Closure{..}, .. }) => tcx.typeck(def_id).node_type(hir_id),
|
Node::Expr(&Expr { kind: ExprKind::Closure { .. }, .. }) => {
|
||||||
|
tcx.typeck(def_id).node_type(hir_id)
|
||||||
|
}
|
||||||
|
|
||||||
Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
|
Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
|
||||||
// We defer to `type_of` of the corresponding parameter
|
// We defer to `type_of` of the corresponding parameter
|
||||||
|
@ -410,40 +417,91 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||||
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
|
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
|
||||||
if asm.operands.iter().any(|(op, _op_sp)| match op {
|
if asm.operands.iter().any(|(op, _op_sp)| match op {
|
||||||
hir::InlineAsmOperand::Const { anon_const }
|
hir::InlineAsmOperand::Const { anon_const }
|
||||||
| hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
|
| hir::InlineAsmOperand::SymFn { anon_const } => {
|
||||||
|
anon_const.hir_id == hir_id
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}) =>
|
}) =>
|
||||||
{
|
{
|
||||||
tcx.typeck(def_id).node_type(hir_id)
|
tcx.typeck(def_id).node_type(hir_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => tcx
|
Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
|
||||||
.adt_def(tcx.hir().get_parent_item(hir_id))
|
tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
|
||||||
.repr()
|
}
|
||||||
.discr_type()
|
|
||||||
.to_ty(tcx),
|
|
||||||
|
|
||||||
Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. })
|
Node::TypeBinding(
|
||||||
if let Node::TraitRef(trait_ref) = tcx.hir().get(
|
binding @ &TypeBinding {
|
||||||
tcx.hir().get_parent_node(binding_id)
|
hir_id: binding_id,
|
||||||
) =>
|
kind: TypeBindingKind::Equality { term: Term::Const(ref e) },
|
||||||
|
..
|
||||||
|
},
|
||||||
|
) if let Node::TraitRef(trait_ref) =
|
||||||
|
tcx.hir().get(tcx.hir().get_parent_node(binding_id))
|
||||||
|
&& e.hir_id == hir_id =>
|
||||||
{
|
{
|
||||||
let Some(trait_def_id) = trait_ref.trait_def_id() else {
|
let Some(trait_def_id) = trait_ref.trait_def_id() else {
|
||||||
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
|
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
|
||||||
};
|
};
|
||||||
let assoc_items = tcx.associated_items(trait_def_id);
|
let assoc_items = tcx.associated_items(trait_def_id);
|
||||||
let assoc_item = assoc_items.find_by_name_and_kind(
|
let assoc_item = assoc_items.find_by_name_and_kind(
|
||||||
tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(),
|
tcx,
|
||||||
);
|
binding.ident,
|
||||||
if let Some(assoc_item) = assoc_item {
|
ty::AssocKind::Const,
|
||||||
tcx.type_of(assoc_item.def_id)
|
def_id.to_def_id(),
|
||||||
} else {
|
);
|
||||||
// FIXME(associated_const_equality): add a useful error message here.
|
if let Some(assoc_item) = assoc_item {
|
||||||
tcx.ty_error_with_message(
|
tcx.type_of(assoc_item.def_id)
|
||||||
DUMMY_SP,
|
} else {
|
||||||
"Could not find associated const on trait",
|
// FIXME(associated_const_equality): add a useful error message here.
|
||||||
)
|
tcx.ty_error_with_message(
|
||||||
}
|
DUMMY_SP,
|
||||||
|
"Could not find associated const on trait",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::TypeBinding(
|
||||||
|
binding @ &TypeBinding { hir_id: binding_id, gen_args, ref kind, .. },
|
||||||
|
) if let Node::TraitRef(trait_ref) =
|
||||||
|
tcx.hir().get(tcx.hir().get_parent_node(binding_id))
|
||||||
|
&& let Some((idx, _)) =
|
||||||
|
gen_args.args.iter().enumerate().find(|(_, arg)| {
|
||||||
|
if let GenericArg::Const(ct) = arg {
|
||||||
|
ct.value.hir_id == hir_id
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}) =>
|
||||||
|
{
|
||||||
|
let Some(trait_def_id) = trait_ref.trait_def_id() else {
|
||||||
|
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
|
||||||
|
};
|
||||||
|
let assoc_items = tcx.associated_items(trait_def_id);
|
||||||
|
let assoc_item = assoc_items.find_by_name_and_kind(
|
||||||
|
tcx,
|
||||||
|
binding.ident,
|
||||||
|
match kind {
|
||||||
|
// I think `<A: T>` type bindings requires that `A` is a type
|
||||||
|
TypeBindingKind::Constraint { .. }
|
||||||
|
| TypeBindingKind::Equality { term: Term::Ty(..) } => {
|
||||||
|
ty::AssocKind::Type
|
||||||
|
}
|
||||||
|
TypeBindingKind::Equality { term: Term::Const(..) } => {
|
||||||
|
ty::AssocKind::Const
|
||||||
|
}
|
||||||
|
},
|
||||||
|
def_id.to_def_id(),
|
||||||
|
);
|
||||||
|
if let Some(assoc_item) = assoc_item {
|
||||||
|
tcx.type_of(tcx.generics_of(assoc_item.def_id).params[idx].def_id)
|
||||||
|
} else {
|
||||||
|
// FIXME(associated_const_equality): add a useful error message here.
|
||||||
|
tcx.ty_error_with_message(
|
||||||
|
DUMMY_SP,
|
||||||
|
"Could not find associated const on trait",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::GenericParam(&GenericParam {
|
Node::GenericParam(&GenericParam {
|
||||||
|
@ -452,8 +510,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||||
..
|
..
|
||||||
}) if ct.hir_id == hir_id => tcx.type_of(tcx.hir().local_def_id(param_hir_id)),
|
}) if ct.hir_id == hir_id => tcx.type_of(tcx.hir().local_def_id(param_hir_id)),
|
||||||
|
|
||||||
x =>
|
x => tcx.ty_error_with_message(
|
||||||
tcx.ty_error_with_message(
|
|
||||||
DUMMY_SP,
|
DUMMY_SP,
|
||||||
&format!("unexpected const parent in type_of(): {x:?}"),
|
&format!("unexpected const parent in type_of(): {x:?}"),
|
||||||
),
|
),
|
||||||
|
|
|
@ -97,30 +97,28 @@ fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr {
|
||||||
|
|
||||||
impl EarlyLintPass for WhileTrue {
|
impl EarlyLintPass for WhileTrue {
|
||||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||||
if let ast::ExprKind::While(cond, _, label) = &e.kind {
|
if let ast::ExprKind::While(cond, _, label) = &e.kind
|
||||||
if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind {
|
&& let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind
|
||||||
if let ast::LitKind::Bool(true) = lit.kind {
|
&& let ast::LitKind::Bool(true) = lit.kind
|
||||||
if !lit.span.from_expansion() {
|
&& !lit.span.from_expansion()
|
||||||
let condition_span = e.span.with_hi(cond.span.hi());
|
{
|
||||||
cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| {
|
let condition_span = e.span.with_hi(cond.span.hi());
|
||||||
lint.build(fluent::lint::builtin_while_true)
|
cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| {
|
||||||
.span_suggestion_short(
|
lint.build(fluent::lint::builtin_while_true)
|
||||||
condition_span,
|
.span_suggestion_short(
|
||||||
fluent::lint::suggestion,
|
condition_span,
|
||||||
format!(
|
fluent::lint::suggestion,
|
||||||
"{}loop",
|
format!(
|
||||||
label.map_or_else(String::new, |label| format!(
|
"{}loop",
|
||||||
"{}: ",
|
label.map_or_else(String::new, |label| format!(
|
||||||
label.ident,
|
"{}: ",
|
||||||
))
|
label.ident,
|
||||||
),
|
))
|
||||||
Applicability::MachineApplicable,
|
),
|
||||||
)
|
Applicability::MachineApplicable,
|
||||||
.emit();
|
)
|
||||||
})
|
.emit();
|
||||||
}
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,7 +440,7 @@ pub trait TryInto<T>: Sized {
|
||||||
///
|
///
|
||||||
/// fn try_from(value: i32) -> Result<Self, Self::Error> {
|
/// fn try_from(value: i32) -> Result<Self, Self::Error> {
|
||||||
/// if value <= 0 {
|
/// if value <= 0 {
|
||||||
/// Err("GreaterThanZero only accepts value superior than zero!")
|
/// Err("GreaterThanZero only accepts values greater than zero!")
|
||||||
/// } else {
|
/// } else {
|
||||||
/// Ok(GreaterThanZero(value))
|
/// Ok(GreaterThanZero(value))
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -2431,22 +2431,13 @@ pub trait Iterator {
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// Find the maximum value:
|
|
||||||
///
|
|
||||||
/// ```
|
/// ```
|
||||||
/// fn find_max<I>(iter: I) -> Option<I::Item>
|
/// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap();
|
||||||
/// where I: Iterator,
|
/// assert_eq!(reduced, 45);
|
||||||
/// I::Item: Ord,
|
|
||||||
/// {
|
|
||||||
/// iter.reduce(|accum, item| {
|
|
||||||
/// if accum >= item { accum } else { item }
|
|
||||||
/// })
|
|
||||||
/// }
|
|
||||||
/// let a = [10, 20, 5, -23, 0];
|
|
||||||
/// let b: [u32; 0] = [];
|
|
||||||
///
|
///
|
||||||
/// assert_eq!(find_max(a.iter()), Some(&20));
|
/// // Which is equivalent to doing it with `fold`:
|
||||||
/// assert_eq!(find_max(b.iter()), None);
|
/// let folded: i32 = (1..10).fold(0, |acc, e| acc + e);
|
||||||
|
/// assert_eq!(reduced, folded);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "iterator_fold_self", since = "1.51.0")]
|
#[stable(feature = "iterator_fold_self", since = "1.51.0")]
|
||||||
|
|
|
@ -721,6 +721,160 @@ macro_rules! nonzero_signed_operations {
|
||||||
// SAFETY: absolute value of nonzero cannot yield zero values.
|
// SAFETY: absolute value of nonzero cannot yield zero values.
|
||||||
unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) }
|
unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if `self` is negative and `false` if the
|
||||||
|
/// number is positive.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(nonzero_negation_ops)]
|
||||||
|
///
|
||||||
|
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
|
||||||
|
/// # fn main() { test().unwrap(); }
|
||||||
|
/// # fn test() -> Option<()> {
|
||||||
|
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
|
||||||
|
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
|
||||||
|
///
|
||||||
|
/// assert!(neg_five.is_negative());
|
||||||
|
/// assert!(!pos_five.is_negative());
|
||||||
|
/// # Some(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[must_use]
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "nonzero_negation_ops", issue = "102443")]
|
||||||
|
pub const fn is_negative(self) -> bool {
|
||||||
|
self.get().is_negative()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checked negation. Computes `-self`, returning `None` if `self == i32::MIN`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(nonzero_negation_ops)]
|
||||||
|
///
|
||||||
|
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
|
||||||
|
/// # fn main() { test().unwrap(); }
|
||||||
|
/// # fn test() -> Option<()> {
|
||||||
|
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
|
||||||
|
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
|
||||||
|
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
|
||||||
|
stringify!($Int), "::MIN)?;")]
|
||||||
|
///
|
||||||
|
/// assert_eq!(pos_five.checked_neg(), Some(neg_five));
|
||||||
|
/// assert_eq!(min.checked_neg(), None);
|
||||||
|
/// # Some(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "nonzero_negation_ops", issue = "102443")]
|
||||||
|
pub const fn checked_neg(self) -> Option<$Ty> {
|
||||||
|
if let Some(result) = self.get().checked_neg() {
|
||||||
|
// SAFETY: negation of nonzero cannot yield zero values.
|
||||||
|
return Some(unsafe { $Ty::new_unchecked(result) });
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Negates self, overflowing if this is equal to the minimum value.
|
||||||
|
///
|
||||||
|
#[doc = concat!("See [`", stringify!($Int), "::overflowing_neg`]")]
|
||||||
|
/// for documentation on overflow behaviour.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(nonzero_negation_ops)]
|
||||||
|
///
|
||||||
|
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
|
||||||
|
/// # fn main() { test().unwrap(); }
|
||||||
|
/// # fn test() -> Option<()> {
|
||||||
|
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
|
||||||
|
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
|
||||||
|
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
|
||||||
|
stringify!($Int), "::MIN)?;")]
|
||||||
|
///
|
||||||
|
/// assert_eq!(pos_five.overflowing_neg(), (neg_five, false));
|
||||||
|
/// assert_eq!(min.overflowing_neg(), (min, true));
|
||||||
|
/// # Some(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "nonzero_negation_ops", issue = "102443")]
|
||||||
|
pub const fn overflowing_neg(self) -> ($Ty, bool) {
|
||||||
|
let (result, overflow) = self.get().overflowing_neg();
|
||||||
|
// SAFETY: negation of nonzero cannot yield zero values.
|
||||||
|
((unsafe { $Ty::new_unchecked(result) }), overflow)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Saturating negation. Computes `-self`, returning `MAX` if
|
||||||
|
/// `self == i32::MIN` instead of overflowing.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(nonzero_negation_ops)]
|
||||||
|
///
|
||||||
|
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
|
||||||
|
/// # fn main() { test().unwrap(); }
|
||||||
|
/// # fn test() -> Option<()> {
|
||||||
|
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
|
||||||
|
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
|
||||||
|
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
|
||||||
|
stringify!($Int), "::MIN)?;")]
|
||||||
|
#[doc = concat!("let min_plus_one = ", stringify!($Ty), "::new(",
|
||||||
|
stringify!($Int), "::MIN + 1)?;")]
|
||||||
|
#[doc = concat!("let max = ", stringify!($Ty), "::new(",
|
||||||
|
stringify!($Int), "::MAX)?;")]
|
||||||
|
///
|
||||||
|
/// assert_eq!(pos_five.saturating_neg(), neg_five);
|
||||||
|
/// assert_eq!(min.saturating_neg(), max);
|
||||||
|
/// assert_eq!(max.saturating_neg(), min_plus_one);
|
||||||
|
/// # Some(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "nonzero_negation_ops", issue = "102443")]
|
||||||
|
pub const fn saturating_neg(self) -> $Ty {
|
||||||
|
if let Some(result) = self.checked_neg() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
$Ty::MAX
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary
|
||||||
|
/// of the type.
|
||||||
|
///
|
||||||
|
#[doc = concat!("See [`", stringify!($Int), "::wrapping_neg`]")]
|
||||||
|
/// for documentation on overflow behaviour.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(nonzero_negation_ops)]
|
||||||
|
///
|
||||||
|
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
|
||||||
|
/// # fn main() { test().unwrap(); }
|
||||||
|
/// # fn test() -> Option<()> {
|
||||||
|
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
|
||||||
|
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
|
||||||
|
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
|
||||||
|
stringify!($Int), "::MIN)?;")]
|
||||||
|
///
|
||||||
|
/// assert_eq!(pos_five.wrapping_neg(), neg_five);
|
||||||
|
/// assert_eq!(min.wrapping_neg(), min);
|
||||||
|
/// # Some(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "nonzero_negation_ops", issue = "102443")]
|
||||||
|
pub const fn wrapping_neg(self) -> $Ty {
|
||||||
|
let result = self.get().wrapping_neg();
|
||||||
|
// SAFETY: negation of nonzero cannot yield zero values.
|
||||||
|
unsafe { $Ty::new_unchecked(result) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,6 +191,7 @@ h4.code-header {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#crate-search,
|
||||||
h1, h2, h3, h4, h5, h6,
|
h1, h2, h3, h4, h5, h6,
|
||||||
.sidebar,
|
.sidebar,
|
||||||
.mobile-topbar,
|
.mobile-topbar,
|
||||||
|
@ -304,16 +305,6 @@ summary {
|
||||||
|
|
||||||
/* Fix some style changes due to normalize.css 8 */
|
/* Fix some style changes due to normalize.css 8 */
|
||||||
|
|
||||||
button,
|
|
||||||
input,
|
|
||||||
optgroup,
|
|
||||||
select,
|
|
||||||
textarea {
|
|
||||||
color: inherit;
|
|
||||||
font: inherit;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
button {
|
||||||
/* Buttons on Safari have different default padding than other platforms. Make them the same. */
|
/* Buttons on Safari have different default padding than other platforms. Make them the same. */
|
||||||
padding: 1px 6px;
|
padding: 1px 6px;
|
||||||
|
@ -887,6 +878,9 @@ table,
|
||||||
/* Removes default arrow from firefox */
|
/* Removes default arrow from firefox */
|
||||||
text-indent: 0.01px;
|
text-indent: 0.01px;
|
||||||
background-color: var(--main-background-color);
|
background-color: var(--main-background-color);
|
||||||
|
color: inherit;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
/* cancel stylistic differences in padding in firefox
|
/* cancel stylistic differences in padding in firefox
|
||||||
for "appearance: none"-style (or equivalent) <select>s */
|
for "appearance: none"-style (or equivalent) <select>s */
|
||||||
|
@ -1363,6 +1357,8 @@ pre.rust {
|
||||||
border: 0;
|
border: 0;
|
||||||
border-top: 2px solid;
|
border-top: 2px solid;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#titles > button > div.count {
|
#titles > button > div.count {
|
||||||
|
@ -1380,7 +1376,6 @@ pre.rust {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1400,6 +1395,8 @@ pre.rust {
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
}
|
}
|
||||||
#sidebar-toggle > button {
|
#sidebar-toggle > button {
|
||||||
|
font-size: inherit;
|
||||||
|
font-weight: bold;
|
||||||
background: none;
|
background: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -1428,6 +1425,7 @@ pre.rust {
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#settings-menu > a, #help-button > button {
|
#settings-menu > a, #help-button > button {
|
||||||
|
@ -1887,7 +1885,6 @@ in storage.js plus the media query with (min-width: 701px)
|
||||||
border-top-right-radius: 3px;
|
border-top-right-radius: 3px;
|
||||||
border-bottom-right-radius: 3px;
|
border-bottom-right-radius: 3px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: bold;
|
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
margin-right: 0.3em;
|
margin-right: 0.3em;
|
||||||
height: 1.2rem;
|
height: 1.2rem;
|
||||||
width: 1.2rem;
|
width: 1.2rem;
|
||||||
border: 1px solid;
|
color: inherit;
|
||||||
|
border: 1px solid currentColor;
|
||||||
outline: none;
|
outline: none;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
15
src/test/ui/generic-associated-types/issue-102333.rs
Normal file
15
src/test/ui/generic-associated-types/issue-102333.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
trait A {
|
||||||
|
type T: B<U<1i32> = ()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait B {
|
||||||
|
type U<const C: i32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f<T: A>() {
|
||||||
|
let _: <<T as A>::T as B>::U<1i32> = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue