mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Auto merge of #120281 - fmease:rollup-9nxail8, r=fmease
Rollup of 10 pull requests Successful merges: - #119028 (Add more weirdness to weird-exprs.rs) - #119805 (Suggest array::from_fn for array initialization) - #120188 (compiler: update freebsd and netbsd base specs.) - #120215 (Update some deps with `bitflags` v1 dependencies) - #120244 (Use `Self` in `NonZero*` implementations.) - #120246 (Re-add estebank to review rotation) - #120252 (rename `RawTy` to `LoweredTy`) - #120255 (correct my mailmap entry) - #120270 (A bunch of random modifications) - #120280 (Move condition enabling the pass to `is_enabled`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
5d3d3479d7
2
.mailmap
2
.mailmap
@ -129,7 +129,7 @@ Clement Miao <clementmiao@gmail.com>
|
||||
Clément Renault <renault.cle@gmail.com>
|
||||
Cliff Dyer <jcd@sdf.org>
|
||||
Clinton Ryan <clint.ryan3@gmail.com>
|
||||
Corey Richardson <corey@octayn.net> Elaine "See More" Nemo <corey@octayn.net>
|
||||
ember arlynx <ember@lunar.town> <corey@octayn.net>
|
||||
Crazycolorz5 <Crazycolorz5@gmail.com>
|
||||
csmoe <35686186+csmoe@users.noreply.github.com>
|
||||
Cyryl Płotnicki <cyplo@cyplo.net>
|
||||
|
89
Cargo.lock
89
Cargo.lock
@ -878,12 +878,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.4.0"
|
||||
version = "3.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e"
|
||||
checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2512,14 +2512,13 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.2"
|
||||
version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
|
||||
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags 2.4.1",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2641,11 +2640,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.55"
|
||||
version = "0.10.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
|
||||
checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags 2.4.1",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
@ -2673,9 +2672,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.90"
|
||||
version = "0.9.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
|
||||
checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@ -6143,6 +6142,15 @@ dependencies = [
|
||||
"windows-targets 0.48.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
@ -6173,6 +6181,21 @@ dependencies = [
|
||||
"windows_x86_64_msvc 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.0",
|
||||
"windows_aarch64_msvc 0.52.0",
|
||||
"windows_i686_gnu 0.52.0",
|
||||
"windows_i686_msvc 0.52.0",
|
||||
"windows_x86_64_gnu 0.52.0",
|
||||
"windows_x86_64_gnullvm 0.52.0",
|
||||
"windows_x86_64_msvc 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
@ -6185,6 +6208,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
@ -6197,6 +6226,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
@ -6209,6 +6244,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
@ -6221,6 +6262,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
@ -6233,6 +6280,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
@ -6245,6 +6298,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
@ -6257,6 +6316,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.4.7"
|
||||
|
@ -12,7 +12,9 @@ use rustc_trait_selection::traits::StructurallyNormalizeExt;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum AutoderefKind {
|
||||
/// A true pointer type, such as `&T` and `*mut T`.
|
||||
Builtin,
|
||||
/// A type which must dispatch to a `Deref` implementation.
|
||||
Overloaded,
|
||||
}
|
||||
|
||||
@ -83,6 +85,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
|
||||
(AutoderefKind::Builtin, ty)
|
||||
}
|
||||
} else if let Some(ty) = self.overloaded_deref_ty(self.state.cur_ty) {
|
||||
// The overloaded deref check already normalizes the pointee type.
|
||||
(AutoderefKind::Overloaded, ty)
|
||||
} else {
|
||||
return None;
|
||||
|
@ -254,7 +254,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||
// checks. For the comparison to be valid, we need to
|
||||
// normalize the associated types in the impl/trait methods
|
||||
// first. However, because function types bind regions, just
|
||||
// calling `normalize_associated_types_in` would have no effect on
|
||||
// calling `FnCtxt::normalize` would have no effect on
|
||||
// any associated types appearing in the fn arguments or return
|
||||
// type.
|
||||
|
||||
|
@ -2,7 +2,7 @@ use crate::callee::{self, DeferredCallResolution};
|
||||
use crate::errors::CtorIsPrivate;
|
||||
use crate::method::{self, MethodCallee, SelfSource};
|
||||
use crate::rvalue_scopes;
|
||||
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, RawTy};
|
||||
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey};
|
||||
@ -373,14 +373,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_raw_ty(&self, span: Span, ty: Ty<'tcx>) -> RawTy<'tcx> {
|
||||
RawTy { raw: ty, normalized: self.normalize(span, ty) }
|
||||
}
|
||||
|
||||
pub fn to_ty(&self, ast_t: &hir::Ty<'tcx>) -> RawTy<'tcx> {
|
||||
pub fn to_ty(&self, ast_t: &hir::Ty<'tcx>) -> LoweredTy<'tcx> {
|
||||
let t = self.astconv().ast_ty_to_ty(ast_t);
|
||||
self.register_wf_obligation(t.into(), ast_t.span, traits::WellFormed(None));
|
||||
self.handle_raw_ty(ast_t.span, t)
|
||||
LoweredTy::from_raw(self, ast_t.span, t)
|
||||
}
|
||||
|
||||
pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||
@ -396,7 +392,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ty.normalized
|
||||
}
|
||||
|
||||
pub(super) fn user_args_for_adt(ty: RawTy<'tcx>) -> UserArgs<'tcx> {
|
||||
pub(super) fn user_args_for_adt(ty: LoweredTy<'tcx>) -> UserArgs<'tcx> {
|
||||
match (ty.raw.kind(), ty.normalized.kind()) {
|
||||
(ty::Adt(_, args), _) => UserArgs { args, user_self_ty: None },
|
||||
(_, ty::Adt(adt, args)) => UserArgs {
|
||||
@ -801,7 +797,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
hir_id: hir::HirId,
|
||||
span: Span,
|
||||
args: Option<&'tcx [hir::Expr<'tcx>]>,
|
||||
) -> (Res, Option<RawTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
|
||||
) -> (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
|
||||
debug!(
|
||||
"resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}",
|
||||
qpath, hir_id, span
|
||||
@ -825,7 +821,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// We manually call `register_wf_obligation` in the success path
|
||||
// below.
|
||||
let ty = self.astconv().ast_ty_to_ty_in_path(qself);
|
||||
(self.handle_raw_ty(span, ty), qself, segment)
|
||||
(LoweredTy::from_raw(self, span, ty), qself, segment)
|
||||
}
|
||||
QPath::LangItem(..) => {
|
||||
bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
|
||||
@ -1074,7 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pub fn instantiate_value_path(
|
||||
&self,
|
||||
segments: &'tcx [hir::PathSegment<'tcx>],
|
||||
self_ty: Option<RawTy<'tcx>>,
|
||||
self_ty: Option<LoweredTy<'tcx>>,
|
||||
res: Res,
|
||||
span: Span,
|
||||
hir_id: hir::HirId,
|
||||
@ -1201,8 +1197,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
path_segs.last().is_some_and(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self);
|
||||
|
||||
let (res, self_ctor_args) = if let Res::SelfCtor(impl_def_id) = res {
|
||||
let ty =
|
||||
self.handle_raw_ty(span, tcx.at(span).type_of(impl_def_id).instantiate_identity());
|
||||
let ty = LoweredTy::from_raw(
|
||||
self,
|
||||
span,
|
||||
tcx.at(span).type_of(impl_def_id).instantiate_identity(),
|
||||
);
|
||||
match ty.normalized.ty_adt_def() {
|
||||
Some(adt_def) if adt_def.has_ctor() => {
|
||||
let (ctor_kind, ctor_def_id) = adt_def.non_enum_variant().ctor.unwrap();
|
||||
|
@ -6,7 +6,7 @@ use crate::method::MethodCallee;
|
||||
use crate::TupleArgumentsFlag::*;
|
||||
use crate::{errors, Expectation::*};
|
||||
use crate::{
|
||||
struct_span_code_err, BreakableCtxt, Diverges, Expectation, FnCtxt, Needs, RawTy,
|
||||
struct_span_code_err, BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy, Needs,
|
||||
TupleArgumentsFlag,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -1792,12 +1792,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
qpath: &QPath<'tcx>,
|
||||
path_span: Span,
|
||||
hir_id: hir::HirId,
|
||||
) -> (Res, RawTy<'tcx>) {
|
||||
) -> (Res, LoweredTy<'tcx>) {
|
||||
match *qpath {
|
||||
QPath::Resolved(ref maybe_qself, path) => {
|
||||
let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself).raw);
|
||||
let ty = self.astconv().res_to_ty(self_ty, path, hir_id, true);
|
||||
(path.res, self.handle_raw_ty(path_span, ty))
|
||||
(path.res, LoweredTy::from_raw(self, path_span, ty))
|
||||
}
|
||||
QPath::TypeRelative(qself, segment) => {
|
||||
let ty = self.to_ty(qself);
|
||||
@ -1808,7 +1808,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let ty = result
|
||||
.map(|(ty, _, _)| ty)
|
||||
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar));
|
||||
let ty = self.handle_raw_ty(path_span, ty);
|
||||
let ty = LoweredTy::from_raw(self, path_span, ty);
|
||||
let result = result.map(|(_, kind, def_id)| (kind, def_id));
|
||||
|
||||
// Write back the new resolution.
|
||||
@ -1818,7 +1818,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
QPath::LangItem(lang_item, span) => {
|
||||
let (res, ty) = self.resolve_lang_item_path(lang_item, span, hir_id);
|
||||
(res, self.handle_raw_ty(path_span, ty))
|
||||
(res, LoweredTy::from_raw(self, path_span, ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -353,14 +353,22 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a user-provided type in the raw form (never normalized).
|
||||
/// The `ty` representation of a user-provided type. Depending on the use-site
|
||||
/// we want to either use the unnormalized or the normalized form of this type.
|
||||
///
|
||||
/// This is a bridge between the interface of `AstConv`, which outputs a raw `Ty`,
|
||||
/// and the API in this module, which expect `Ty` to be fully normalized.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct RawTy<'tcx> {
|
||||
pub struct LoweredTy<'tcx> {
|
||||
/// The unnormalized type provided by the user.
|
||||
pub raw: Ty<'tcx>,
|
||||
|
||||
/// The normalized form of `raw`, stored here for efficiency.
|
||||
pub normalized: Ty<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> LoweredTy<'tcx> {
|
||||
pub fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> {
|
||||
LoweredTy { raw, normalized: fcx.normalize(span, raw) }
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ use crate::check::check_fn;
|
||||
use crate::coercion::DynamicCoerceMany;
|
||||
use crate::diverges::Diverges;
|
||||
use crate::expectation::Expectation;
|
||||
use crate::fn_ctxt::RawTy;
|
||||
use crate::fn_ctxt::LoweredTy;
|
||||
use crate::gather_locals::GatherLocalsVisitor;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::{struct_span_code_err, ErrorGuaranteed};
|
||||
|
@ -746,11 +746,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(item, impl_ty, impl_args);
|
||||
debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty);
|
||||
|
||||
// We can't use normalize_associated_types_in as it will pollute the
|
||||
// We can't use `FnCtxt::normalize` as it will pollute the
|
||||
// fcx's fulfillment context after this probe is over.
|
||||
//
|
||||
// Note: we only normalize `xform_self_ty` here since the normalization
|
||||
// of the return type can lead to inference results that prohibit
|
||||
// valid candidates from being found, see issue #85671
|
||||
//
|
||||
// FIXME Postponing the normalization of the return type likely only hides a deeper bug,
|
||||
// which might be caused by the `param_env` itself. The clauses of the `param_env`
|
||||
// maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::gather_locals::DeclOrigin;
|
||||
use crate::{errors, FnCtxt, RawTy};
|
||||
use crate::{errors, FnCtxt, LoweredTy};
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{
|
||||
@ -891,7 +891,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
pat: &Pat<'tcx>,
|
||||
qpath: &hir::QPath<'_>,
|
||||
path_resolution: (Res, Option<RawTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]),
|
||||
path_resolution: (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]),
|
||||
expected: Ty<'tcx>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
|
@ -804,17 +804,12 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
}
|
||||
} else {
|
||||
p!(print_def_path(did, args));
|
||||
p!(" upvar_tys=(");
|
||||
if !args.as_coroutine().is_valid() {
|
||||
p!("unavailable");
|
||||
} else {
|
||||
self.comma_sep(args.as_coroutine().upvar_tys().iter())?;
|
||||
}
|
||||
p!(")");
|
||||
|
||||
if args.as_coroutine().is_valid() {
|
||||
p!(" ", print(args.as_coroutine().witness()));
|
||||
}
|
||||
p!(
|
||||
" upvar_tys=",
|
||||
print(args.as_coroutine().tupled_upvars_ty()),
|
||||
" witness=",
|
||||
print(args.as_coroutine().witness())
|
||||
);
|
||||
}
|
||||
|
||||
p!("}}")
|
||||
@ -868,19 +863,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
}
|
||||
} else {
|
||||
p!(print_def_path(did, args));
|
||||
if !args.as_closure().is_valid() {
|
||||
p!(" closure_args=(unavailable)");
|
||||
p!(write(" args={}", args.print_as_list()));
|
||||
} else {
|
||||
p!(" closure_kind_ty=", print(args.as_closure().kind_ty()));
|
||||
p!(
|
||||
" closure_sig_as_fn_ptr_ty=",
|
||||
print(args.as_closure().sig_as_fn_ptr_ty())
|
||||
);
|
||||
p!(" upvar_tys=(");
|
||||
self.comma_sep(args.as_closure().upvar_tys().iter())?;
|
||||
p!(")");
|
||||
}
|
||||
p!(
|
||||
" closure_kind_ty=",
|
||||
print(args.as_closure().kind_ty()),
|
||||
" closure_sig_as_fn_ptr_ty=",
|
||||
print(args.as_closure().sig_as_fn_ptr_ty()),
|
||||
" upvar_tys=",
|
||||
print(args.as_closure().tupled_upvars_ty())
|
||||
);
|
||||
}
|
||||
p!("}}");
|
||||
}
|
||||
|
@ -242,9 +242,15 @@ pub struct ClosureArgs<'tcx> {
|
||||
|
||||
/// Struct returned by `split()`.
|
||||
pub struct ClosureArgsParts<'tcx> {
|
||||
/// This is the args of the typeck root.
|
||||
pub parent_args: &'tcx [GenericArg<'tcx>],
|
||||
/// Represents the maximum calling capability of the closure.
|
||||
pub closure_kind_ty: Ty<'tcx>,
|
||||
/// Captures the closure's signature. This closure signature is "tupled", and
|
||||
/// thus has a peculiar signature of `extern "rust-call" fn((Args, ...)) -> Ty`.
|
||||
pub closure_sig_as_fn_ptr_ty: Ty<'tcx>,
|
||||
/// The upvars captured by the closure. Remains an inference variable
|
||||
/// until the upvar analysis, which happens late in HIR typeck.
|
||||
pub tupled_upvars_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
@ -277,15 +283,6 @@ impl<'tcx> ClosureArgs<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` only if enough of the synthetic types are known to
|
||||
/// allow using all of the methods on `ClosureArgs` without panicking.
|
||||
///
|
||||
/// Used primarily by `ty::print::pretty` to be able to handle closure
|
||||
/// types that haven't had their synthetic types substituted in.
|
||||
pub fn is_valid(self) -> bool {
|
||||
self.args.len() >= 3 && matches!(self.split().tupled_upvars_ty.kind(), Tuple(_))
|
||||
}
|
||||
|
||||
/// Returns the substitutions of the closure's parent.
|
||||
pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
|
||||
self.split().parent_args
|
||||
@ -296,9 +293,9 @@ impl<'tcx> ClosureArgs<'tcx> {
|
||||
/// empty iterator is returned.
|
||||
#[inline]
|
||||
pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
|
||||
match self.tupled_upvars_ty().kind() {
|
||||
match *self.tupled_upvars_ty().kind() {
|
||||
TyKind::Error(_) => ty::List::empty(),
|
||||
TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
|
||||
TyKind::Tuple(tys) => tys,
|
||||
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
|
||||
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
|
||||
}
|
||||
@ -337,10 +334,9 @@ impl<'tcx> ClosureArgs<'tcx> {
|
||||
|
||||
/// Extracts the signature from the closure.
|
||||
pub fn sig(self) -> ty::PolyFnSig<'tcx> {
|
||||
let ty = self.sig_as_fn_ptr_ty();
|
||||
match ty.kind() {
|
||||
ty::FnPtr(sig) => *sig,
|
||||
_ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()),
|
||||
match *self.sig_as_fn_ptr_ty().kind() {
|
||||
ty::FnPtr(sig) => sig,
|
||||
ty => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {ty:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,11 +352,17 @@ pub struct CoroutineArgs<'tcx> {
|
||||
}
|
||||
|
||||
pub struct CoroutineArgsParts<'tcx> {
|
||||
/// This is the args of the typeck root.
|
||||
pub parent_args: &'tcx [GenericArg<'tcx>],
|
||||
pub resume_ty: Ty<'tcx>,
|
||||
pub yield_ty: Ty<'tcx>,
|
||||
pub return_ty: Ty<'tcx>,
|
||||
/// The interior type of the coroutine.
|
||||
/// Represents all types that are stored in locals
|
||||
/// in the coroutine's body.
|
||||
pub witness: Ty<'tcx>,
|
||||
/// The upvars captured by the closure. Remains an inference variable
|
||||
/// until the upvar analysis, which happens late in HIR typeck.
|
||||
pub tupled_upvars_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
@ -397,15 +399,6 @@ impl<'tcx> CoroutineArgs<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` only if enough of the synthetic types are known to
|
||||
/// allow using all of the methods on `CoroutineArgs` without panicking.
|
||||
///
|
||||
/// Used primarily by `ty::print::pretty` to be able to handle coroutine
|
||||
/// types that haven't had their synthetic types substituted in.
|
||||
pub fn is_valid(self) -> bool {
|
||||
self.args.len() >= 5 && matches!(self.split().tupled_upvars_ty.kind(), Tuple(_))
|
||||
}
|
||||
|
||||
/// Returns the substitutions of the coroutine's parent.
|
||||
pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
|
||||
self.split().parent_args
|
||||
@ -425,9 +418,9 @@ impl<'tcx> CoroutineArgs<'tcx> {
|
||||
/// empty iterator is returned.
|
||||
#[inline]
|
||||
pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
|
||||
match self.tupled_upvars_ty().kind() {
|
||||
match *self.tupled_upvars_ty().kind() {
|
||||
TyKind::Error(_) => ty::List::empty(),
|
||||
TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
|
||||
TyKind::Tuple(tys) => tys,
|
||||
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
|
||||
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
|
||||
}
|
||||
|
@ -7,14 +7,10 @@ pub struct RemoveStorageMarkers;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for RemoveStorageMarkers {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() > 0
|
||||
sess.mir_opt_level() > 0 && !sess.emit_lifetime_markers()
|
||||
}
|
||||
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
if tcx.sess.emit_lifetime_markers() {
|
||||
return;
|
||||
}
|
||||
|
||||
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
trace!("Running RemoveStorageMarkers on {:?}", body.source);
|
||||
for data in body.basic_blocks.as_mut_preserves_cfg() {
|
||||
data.statements.retain(|statement| match statement.kind {
|
||||
|
@ -8,6 +8,7 @@ pub fn opts() -> TargetOptions {
|
||||
has_rpath: true,
|
||||
position_independent_executables: true,
|
||||
relro_level: RelroLevel::Full,
|
||||
has_thread_local: true,
|
||||
default_dwarf_version: 2,
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ pub fn opts() -> TargetOptions {
|
||||
crt_static_respected: true,
|
||||
position_independent_executables: true,
|
||||
relro_level: RelroLevel::Full,
|
||||
has_thread_local: true,
|
||||
abi_return_struct_as_int: true,
|
||||
default_dwarf_version: 2,
|
||||
..Default::default()
|
||||
|
@ -9,6 +9,7 @@ pub fn opts() -> TargetOptions {
|
||||
has_rpath: true,
|
||||
position_independent_executables: true,
|
||||
relro_level: RelroLevel::Full,
|
||||
has_thread_local: true,
|
||||
use_ctors_section: true,
|
||||
default_dwarf_version: 2,
|
||||
..Default::default()
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Computes a normalizes-to (projection) goal for inherent associated types,
|
||||
//! `#![feature(lazy_type_alias)]` and `#![feature(type_alias_impl_trait)]`.
|
||||
//!
|
||||
//! Since a weak alias is not ambiguous, this just computes the `type_of` of
|
||||
//! Since a weak alias is never ambiguous, this just computes the `type_of` of
|
||||
//! the alias and registers the where-clauses of the type alias.
|
||||
use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, QueryResult};
|
||||
use rustc_middle::ty;
|
||||
|
@ -3152,6 +3152,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
],
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
// FIXME: we may suggest array::repeat instead
|
||||
err.help("consider using `core::array::from_fn` to initialize the array");
|
||||
err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information");
|
||||
}
|
||||
|
||||
if self.tcx.sess.is_nightly_build()
|
||||
|
@ -232,32 +232,12 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
|
||||
Ok::<_, NoSolution>(())
|
||||
})?,
|
||||
|
||||
ty::Closure(_, args) => {
|
||||
if !args.as_closure().is_valid() {
|
||||
// By the time this code runs, all type variables ought to
|
||||
// be fully resolved.
|
||||
|
||||
tcx.dcx().span_delayed_bug(
|
||||
span,
|
||||
format!("upvar_tys for closure not found. Expected capture information for closure {ty}",),
|
||||
);
|
||||
return Err(NoSolution);
|
||||
ty::Closure(_, args) => rustc_data_structures::stack::ensure_sufficient_stack(|| {
|
||||
for ty in args.as_closure().upvar_tys() {
|
||||
dtorck_constraint_for_ty_inner(tcx, param_env, span, depth + 1, ty, constraints)?;
|
||||
}
|
||||
|
||||
rustc_data_structures::stack::ensure_sufficient_stack(|| {
|
||||
for ty in args.as_closure().upvar_tys() {
|
||||
dtorck_constraint_for_ty_inner(
|
||||
tcx,
|
||||
param_env,
|
||||
span,
|
||||
depth + 1,
|
||||
ty,
|
||||
constraints,
|
||||
)?;
|
||||
}
|
||||
Ok::<_, NoSolution>(())
|
||||
})?
|
||||
}
|
||||
Ok::<_, NoSolution>(())
|
||||
})?,
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
// rust-lang/rust#49918: types can be constructed, stored
|
||||
@ -283,15 +263,6 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
|
||||
// derived from lifetimes attached to the upvars and resume
|
||||
// argument, and we *do* incorporate those here.
|
||||
let args = args.as_coroutine();
|
||||
if !args.is_valid() {
|
||||
// By the time this code runs, all type variables ought to
|
||||
// be fully resolved.
|
||||
tcx.dcx().span_delayed_bug(
|
||||
span,
|
||||
format!("upvar_tys for coroutine not found. Expected capture information for coroutine {ty}",),
|
||||
);
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
// While we conservatively assume that all coroutines require drop
|
||||
// to avoid query cycles during MIR building, we can check the actual
|
||||
|
@ -141,6 +141,13 @@ where
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
span: Span,
|
||||
) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
|
||||
// In the new trait solver, query type ops are performed locally. This
|
||||
// is because query type ops currently use the old canonicalizer, and
|
||||
// that doesn't preserve things like opaques which have been registered
|
||||
// during MIR typeck. Even after the old canonicalizer is gone, it's
|
||||
// probably worthwhile just keeping this run-locally logic, since we
|
||||
// probably don't gain much from caching here given the new solver does
|
||||
// caching internally.
|
||||
if infcx.next_trait_solver() {
|
||||
return Ok(scrape_region_constraints(
|
||||
infcx,
|
||||
|
@ -317,7 +317,7 @@ macro_rules! nonzero_integer {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn checked_mul(self, other: $Ty) -> Option<$Ty> {
|
||||
pub const fn checked_mul(self, other: Self) -> Option<Self> {
|
||||
if let Some(result) = self.get().checked_mul(other.get()) {
|
||||
// SAFETY:
|
||||
// - `checked_mul` returns `None` on overflow
|
||||
@ -326,7 +326,7 @@ macro_rules! nonzero_integer {
|
||||
// of the sides to be zero
|
||||
//
|
||||
// So the result cannot be zero.
|
||||
Some(unsafe { $Ty::new_unchecked(result) })
|
||||
Some(unsafe { Self::new_unchecked(result) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -356,7 +356,7 @@ macro_rules! nonzero_integer {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn saturating_mul(self, other: $Ty) -> $Ty {
|
||||
pub const fn saturating_mul(self, other: Self) -> Self {
|
||||
// SAFETY:
|
||||
// - `saturating_mul` returns `u*::MAX`/`i*::MAX`/`i*::MIN` on overflow/underflow,
|
||||
// all of which are non-zero
|
||||
@ -365,7 +365,7 @@ macro_rules! nonzero_integer {
|
||||
// of the sides to be zero
|
||||
//
|
||||
// So the result cannot be zero.
|
||||
unsafe { $Ty::new_unchecked(self.get().saturating_mul(other.get())) }
|
||||
unsafe { Self::new_unchecked(self.get().saturating_mul(other.get())) }
|
||||
}
|
||||
|
||||
/// Multiplies two non-zero integers together,
|
||||
@ -403,9 +403,9 @@ macro_rules! nonzero_integer {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const unsafe fn unchecked_mul(self, other: $Ty) -> $Ty {
|
||||
pub const unsafe fn unchecked_mul(self, other: Self) -> Self {
|
||||
// SAFETY: The caller ensures there is no overflow.
|
||||
unsafe { $Ty::new_unchecked(self.get().unchecked_mul(other.get())) }
|
||||
unsafe { Self::new_unchecked(self.get().unchecked_mul(other.get())) }
|
||||
}
|
||||
|
||||
/// Raises non-zero value to an integer power.
|
||||
@ -433,7 +433,7 @@ macro_rules! nonzero_integer {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn checked_pow(self, other: u32) -> Option<$Ty> {
|
||||
pub const fn checked_pow(self, other: u32) -> Option<Self> {
|
||||
if let Some(result) = self.get().checked_pow(other) {
|
||||
// SAFETY:
|
||||
// - `checked_pow` returns `None` on overflow/underflow
|
||||
@ -442,7 +442,7 @@ macro_rules! nonzero_integer {
|
||||
// for base to be zero
|
||||
//
|
||||
// So the result cannot be zero.
|
||||
Some(unsafe { $Ty::new_unchecked(result) })
|
||||
Some(unsafe { Self::new_unchecked(result) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -481,7 +481,7 @@ macro_rules! nonzero_integer {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn saturating_pow(self, other: u32) -> $Ty {
|
||||
pub const fn saturating_pow(self, other: u32) -> Self {
|
||||
// SAFETY:
|
||||
// - `saturating_pow` returns `u*::MAX`/`i*::MAX`/`i*::MIN` on overflow/underflow,
|
||||
// all of which are non-zero
|
||||
@ -490,7 +490,7 @@ macro_rules! nonzero_integer {
|
||||
// for base to be zero
|
||||
//
|
||||
// So the result cannot be zero.
|
||||
unsafe { $Ty::new_unchecked(self.get().saturating_pow(other)) }
|
||||
unsafe { Self::new_unchecked(self.get().saturating_pow(other)) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,29 +508,32 @@ macro_rules! nonzero_integer {
|
||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||
impl BitOr for $Ty {
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn bitor(self, rhs: Self) -> Self::Output {
|
||||
// SAFETY: since `self` and `rhs` are both nonzero, the
|
||||
// result of the bitwise-or will be nonzero.
|
||||
unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
|
||||
unsafe { Self::new_unchecked(self.get() | rhs.get()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||
impl BitOr<$Int> for $Ty {
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn bitor(self, rhs: $Int) -> Self::Output {
|
||||
// SAFETY: since `self` is nonzero, the result of the
|
||||
// bitwise-or will be nonzero regardless of the value of
|
||||
// `rhs`.
|
||||
unsafe { $Ty::new_unchecked(self.get() | rhs) }
|
||||
unsafe { Self::new_unchecked(self.get() | rhs) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||
impl BitOr<$Ty> for $Int {
|
||||
type Output = $Ty;
|
||||
|
||||
#[inline]
|
||||
fn bitor(self, rhs: $Ty) -> Self::Output {
|
||||
// SAFETY: since `rhs` is nonzero, the result of the
|
||||
@ -603,6 +606,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
|
||||
#[stable(feature = "nonzero_div", since = "1.51.0")]
|
||||
impl Div<$Ty> for $Int {
|
||||
type Output = $Int;
|
||||
|
||||
/// This operation rounds towards zero,
|
||||
/// truncating any fractional part of the exact result, and cannot panic.
|
||||
#[inline]
|
||||
@ -616,6 +620,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
|
||||
#[stable(feature = "nonzero_div", since = "1.51.0")]
|
||||
impl Rem<$Ty> for $Int {
|
||||
type Output = $Int;
|
||||
|
||||
/// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
|
||||
#[inline]
|
||||
fn rem(self, other: $Ty) -> $Int {
|
||||
@ -630,12 +635,12 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
|
||||
($Ty:ident signed $Int:ty) => {
|
||||
#[stable(feature = "signed_nonzero_neg", since = "1.71.0")]
|
||||
impl Neg for $Ty {
|
||||
type Output = $Ty;
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn neg(self) -> $Ty {
|
||||
fn neg(self) -> Self {
|
||||
// SAFETY: negation of nonzero cannot yield zero values.
|
||||
unsafe { $Ty::new_unchecked(self.get().neg()) }
|
||||
unsafe { Self::new_unchecked(self.get().neg()) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -703,7 +708,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn checked_add(self, other: $Int) -> Option<$Ty> {
|
||||
pub const fn checked_add(self, other: $Int) -> Option<Self> {
|
||||
if let Some(result) = self.get().checked_add(other) {
|
||||
// SAFETY:
|
||||
// - `checked_add` returns `None` on overflow
|
||||
@ -712,7 +717,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
// sides to be zero
|
||||
//
|
||||
// So the result cannot be zero.
|
||||
Some(unsafe { $Ty::new_unchecked(result) })
|
||||
Some(unsafe { Self::new_unchecked(result) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -742,7 +747,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn saturating_add(self, other: $Int) -> $Ty {
|
||||
pub const fn saturating_add(self, other: $Int) -> Self {
|
||||
// SAFETY:
|
||||
// - `saturating_add` returns `u*::MAX` on overflow, which is non-zero
|
||||
// - `self` is non-zero
|
||||
@ -750,7 +755,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
// sides to be zero
|
||||
//
|
||||
// So the result cannot be zero.
|
||||
unsafe { $Ty::new_unchecked(self.get().saturating_add(other)) }
|
||||
unsafe { Self::new_unchecked(self.get().saturating_add(other)) }
|
||||
}
|
||||
|
||||
/// Adds an unsigned integer to a non-zero value,
|
||||
@ -779,9 +784,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const unsafe fn unchecked_add(self, other: $Int) -> $Ty {
|
||||
pub const unsafe fn unchecked_add(self, other: $Int) -> Self {
|
||||
// SAFETY: The caller ensures there is no overflow.
|
||||
unsafe { $Ty::new_unchecked(self.get().unchecked_add(other)) }
|
||||
unsafe { Self::new_unchecked(self.get().unchecked_add(other)) }
|
||||
}
|
||||
|
||||
/// Returns the smallest power of two greater than or equal to n.
|
||||
@ -812,11 +817,11 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn checked_next_power_of_two(self) -> Option<$Ty> {
|
||||
pub const fn checked_next_power_of_two(self) -> Option<Self> {
|
||||
if let Some(nz) = self.get().checked_next_power_of_two() {
|
||||
// SAFETY: The next power of two is positive
|
||||
// and overflow is checked.
|
||||
Some(unsafe { $Ty::new_unchecked(nz) })
|
||||
Some(unsafe { Self::new_unchecked(nz) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -902,9 +907,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
pub const fn midpoint(self, rhs: Self) -> Self {
|
||||
// SAFETY: The only way to get `0` with midpoint is to have two opposite or
|
||||
// near opposite numbers: (-5, 5), (0, 1), (0, 0) which is impossible because
|
||||
// of the unsignedness of this number and also because $Ty is guaranteed to
|
||||
// of the unsignedness of this number and also because `Self` is guaranteed to
|
||||
// never being 0.
|
||||
unsafe { $Ty::new_unchecked(self.get().midpoint(rhs.get())) }
|
||||
unsafe { Self::new_unchecked(self.get().midpoint(rhs.get())) }
|
||||
}
|
||||
|
||||
/// Returns `true` if and only if `self == (1 << k)` for some `k`.
|
||||
@ -1000,9 +1005,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn abs(self) -> $Ty {
|
||||
pub const fn abs(self) -> Self {
|
||||
// SAFETY: This cannot overflow to zero.
|
||||
unsafe { $Ty::new_unchecked(self.get().abs()) }
|
||||
unsafe { Self::new_unchecked(self.get().abs()) }
|
||||
}
|
||||
|
||||
/// Checked absolute value.
|
||||
@ -1031,10 +1036,10 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn checked_abs(self) -> Option<$Ty> {
|
||||
pub const fn checked_abs(self) -> Option<Self> {
|
||||
if let Some(nz) = self.get().checked_abs() {
|
||||
// SAFETY: absolute value of nonzero cannot yield zero values.
|
||||
Some(unsafe { $Ty::new_unchecked(nz) })
|
||||
Some(unsafe { Self::new_unchecked(nz) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -1066,11 +1071,11 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn overflowing_abs(self) -> ($Ty, bool) {
|
||||
pub const fn overflowing_abs(self) -> (Self, bool) {
|
||||
let (nz, flag) = self.get().overflowing_abs();
|
||||
(
|
||||
// SAFETY: absolute value of nonzero cannot yield zero values.
|
||||
unsafe { $Ty::new_unchecked(nz) },
|
||||
unsafe { Self::new_unchecked(nz) },
|
||||
flag,
|
||||
)
|
||||
}
|
||||
@ -1105,9 +1110,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn saturating_abs(self) -> $Ty {
|
||||
pub const fn saturating_abs(self) -> Self {
|
||||
// SAFETY: absolute value of nonzero cannot yield zero values.
|
||||
unsafe { $Ty::new_unchecked(self.get().saturating_abs()) }
|
||||
unsafe { Self::new_unchecked(self.get().saturating_abs()) }
|
||||
}
|
||||
|
||||
/// Wrapping absolute value, see
|
||||
@ -1138,9 +1143,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn wrapping_abs(self) -> $Ty {
|
||||
pub const fn wrapping_abs(self) -> Self {
|
||||
// SAFETY: absolute value of nonzero cannot yield zero values.
|
||||
unsafe { $Ty::new_unchecked(self.get().wrapping_abs()) }
|
||||
unsafe { Self::new_unchecked(self.get().wrapping_abs()) }
|
||||
}
|
||||
|
||||
/// Computes the absolute value of self
|
||||
@ -1250,10 +1255,10 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[inline]
|
||||
#[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
|
||||
#[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
|
||||
pub const fn checked_neg(self) -> Option<$Ty> {
|
||||
pub const fn checked_neg(self) -> Option<Self> {
|
||||
if let Some(result) = self.get().checked_neg() {
|
||||
// SAFETY: negation of nonzero cannot yield zero values.
|
||||
return Some(unsafe { $Ty::new_unchecked(result) });
|
||||
return Some(unsafe { Self::new_unchecked(result) });
|
||||
}
|
||||
None
|
||||
}
|
||||
@ -1282,10 +1287,10 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[inline]
|
||||
#[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
|
||||
#[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
|
||||
pub const fn overflowing_neg(self) -> ($Ty, bool) {
|
||||
pub const fn overflowing_neg(self) -> (Self, bool) {
|
||||
let (result, overflow) = self.get().overflowing_neg();
|
||||
// SAFETY: negation of nonzero cannot yield zero values.
|
||||
((unsafe { $Ty::new_unchecked(result) }), overflow)
|
||||
((unsafe { Self::new_unchecked(result) }), overflow)
|
||||
}
|
||||
|
||||
/// Saturating negation. Computes `-self`,
|
||||
@ -1317,11 +1322,11 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[inline]
|
||||
#[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
|
||||
#[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
|
||||
pub const fn saturating_neg(self) -> $Ty {
|
||||
pub const fn saturating_neg(self) -> Self {
|
||||
if let Some(result) = self.checked_neg() {
|
||||
return result;
|
||||
}
|
||||
$Ty::MAX
|
||||
Self::MAX
|
||||
}
|
||||
|
||||
/// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary
|
||||
@ -1349,10 +1354,10 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
#[inline]
|
||||
#[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
|
||||
#[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
|
||||
pub const fn wrapping_neg(self) -> $Ty {
|
||||
pub const fn wrapping_neg(self) -> Self {
|
||||
let result = self.get().wrapping_neg();
|
||||
// SAFETY: negation of nonzero cannot yield zero values.
|
||||
unsafe { $Ty::new_unchecked(result) }
|
||||
unsafe { Self::new_unchecked(result) }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -17,7 +17,10 @@
|
||||
target_os = "android",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
target_os = "hurd"
|
||||
target_os = "hurd",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "dragonfly"
|
||||
))]
|
||||
// FIXME: The Rust compiler currently omits weakly function definitions (i.e.,
|
||||
// __cxa_thread_atexit_impl) and its metadata from LLVM IR.
|
||||
|
@ -5,6 +5,8 @@ LL | let headers = [Header{value: &[]}; 128];
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
|
||||
|
|
||||
= note: the `Copy` trait is required because this value will be copied for each element of the array
|
||||
= help: consider using `core::array::from_fn` to initialize the array
|
||||
= help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information
|
||||
help: consider annotating `Header<'_>` with `#[derive(Copy)]`
|
||||
|
|
||||
LL + #[derive(Copy)]
|
||||
@ -18,6 +20,8 @@ LL | let headers = [Header{value: &[0]}; 128];
|
||||
| ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
|
||||
|
|
||||
= note: the `Copy` trait is required because this value will be copied for each element of the array
|
||||
= help: consider using `core::array::from_fn` to initialize the array
|
||||
= help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information
|
||||
help: consider annotating `Header<'_>` with `#[derive(Copy)]`
|
||||
|
|
||||
LL + #[derive(Copy)]
|
||||
|
@ -9,7 +9,7 @@ LL | let c1 : () = c;
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found closure `{mod1::f<T>::{closure#0} closure_args=(unavailable) args=[T, ?8t, extern "rust-call" fn(()), ?7t]}`
|
||||
found closure `{mod1::f<T>::{closure#0} closure_kind_ty=?8t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?7t}`
|
||||
help: use parentheses to call this closure
|
||||
|
|
||||
LL | let c1 : () = c();
|
||||
|
@ -9,7 +9,7 @@ LL | let c1 : () = c;
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found closure `{f<T>::{closure#0} closure_args=(unavailable) args=[T, ?8t, extern "rust-call" fn(()), ?7t]}`
|
||||
found closure `{f<T>::{closure#0} closure_kind_ty=?8t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?7t}`
|
||||
help: use parentheses to call this closure
|
||||
|
|
||||
LL | let c1 : () = c();
|
||||
|
@ -7,7 +7,7 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected fn pointer `fn(u8) -> u8`
|
||||
found closure `{main::{closure#0} closure_args=(unavailable) args=[i8, extern "rust-call" fn((u8,)) -> u8, ?4t]}`
|
||||
found closure `{main::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn((u8,)) -> u8 upvar_tys=?4t}`
|
||||
note: closures can only be coerced to `fn` types if they do not capture any variables
|
||||
--> $DIR/closure-print-verbose.rs:10:39
|
||||
|
|
||||
|
@ -5,6 +5,8 @@ LL | [x; { N }]
|
||||
| ^ the trait `Copy` is not implemented for `T`
|
||||
|
|
||||
= note: the `Copy` trait is required because this value will be copied for each element of the array
|
||||
= help: consider using `core::array::from_fn` to initialize the array
|
||||
= help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | fn g<T: std::marker::Copy, const N: usize>(x: T) -> [T; N] {
|
||||
|
@ -5,6 +5,8 @@ LL | [x; N]
|
||||
| ^ the trait `Copy` is not implemented for `T`
|
||||
|
|
||||
= note: the `Copy` trait is required because this value will be copied for each element of the array
|
||||
= help: consider using `core::array::from_fn` to initialize the array
|
||||
= help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | fn g<T: std::marker::Copy, const N: usize>(x: T) -> [T; N] {
|
||||
|
@ -6,6 +6,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2];
|
||||
|
|
||||
= note: required for `Option<Bar>` to implement `Copy`
|
||||
= note: the `Copy` trait is required because this value will be copied for each element of the array
|
||||
= help: consider using `core::array::from_fn` to initialize the array
|
||||
= help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information
|
||||
help: consider annotating `Bar` with `#[derive(Copy)]`
|
||||
|
|
||||
LL + #[derive(Copy)]
|
||||
@ -20,6 +22,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2];
|
||||
|
|
||||
= note: required for `Option<Bar>` to implement `Copy`
|
||||
= note: the `Copy` trait is required because this value will be copied for each element of the array
|
||||
= help: consider using `core::array::from_fn` to initialize the array
|
||||
= help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information
|
||||
help: consider annotating `Bar` with `#[derive(Copy)]`
|
||||
|
|
||||
LL + #[derive(Copy)]
|
||||
|
@ -6,6 +6,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2];
|
||||
|
|
||||
= note: required for `Option<Bar>` to implement `Copy`
|
||||
= note: the `Copy` trait is required because this value will be copied for each element of the array
|
||||
= help: consider using `core::array::from_fn` to initialize the array
|
||||
= help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information
|
||||
help: consider annotating `Bar` with `#[derive(Copy)]`
|
||||
|
|
||||
LL + #[derive(Copy)]
|
||||
@ -20,6 +22,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2];
|
||||
|
|
||||
= note: required for `Option<Bar>` to implement `Copy`
|
||||
= note: the `Copy` trait is required because this value will be copied for each element of the array
|
||||
= help: consider using `core::array::from_fn` to initialize the array
|
||||
= help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information
|
||||
help: consider annotating `Bar` with `#[derive(Copy)]`
|
||||
|
|
||||
LL + #[derive(Copy)]
|
||||
|
@ -4,7 +4,7 @@ error: coroutine cannot be shared between threads safely
|
||||
LL | assert_sync(|| {
|
||||
| ^^^^^^^^^^^ coroutine is not `Sync`
|
||||
|
|
||||
= help: within `{main::{closure#0} upvar_tys=() {main::{closure#0}}}`, the trait `Sync` is not implemented for `NotSync`
|
||||
= help: within `{main::{closure#0} upvar_tys=() witness={main::{closure#0}}}`, the trait `Sync` is not implemented for `NotSync`
|
||||
note: coroutine is not `Sync` as this value is used across a yield
|
||||
--> $DIR/coroutine-print-verbose-2.rs:20:9
|
||||
|
|
||||
@ -24,7 +24,7 @@ error: coroutine cannot be sent between threads safely
|
||||
LL | assert_send(|| {
|
||||
| ^^^^^^^^^^^ coroutine is not `Send`
|
||||
|
|
||||
= help: within `{main::{closure#1} upvar_tys=() {main::{closure#1}}}`, the trait `Send` is not implemented for `NotSend`
|
||||
= help: within `{main::{closure#1} upvar_tys=() witness={main::{closure#1}}}`, the trait `Send` is not implemented for `NotSend`
|
||||
note: coroutine is not `Send` as this value is used across a yield
|
||||
--> $DIR/coroutine-print-verbose-2.rs:27:9
|
||||
|
|
||||
|
@ -12,7 +12,7 @@ LL | | };
|
||||
| |_____^ expected `()`, found coroutine
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found coroutine `{main::{closure#0} upvar_tys=(unavailable)}`
|
||||
found coroutine `{main::{closure#0} upvar_tys=?4t witness=?6t}`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -5,6 +5,8 @@ LL | let _ = [ a; 5 ];
|
||||
| ^ the trait `Copy` is not implemented for `Foo`
|
||||
|
|
||||
= note: the `Copy` trait is required because this value will be copied for each element of the array
|
||||
= help: consider using `core::array::from_fn` to initialize the array
|
||||
= help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information
|
||||
help: consider annotating `Foo` with `#[derive(Copy)]`
|
||||
|
|
||||
LL + #[derive(Copy)]
|
||||
|
5
tests/ui/trait-bounds/issue-119530-sugg-from-fn.rs
Normal file
5
tests/ui/trait-bounds/issue-119530-sugg-from-fn.rs
Normal file
@ -0,0 +1,5 @@
|
||||
fn foo() -> String { String::new() }
|
||||
|
||||
fn main() {
|
||||
let string_arr = [foo(); 64]; //~ ERROR the trait bound `String: Copy` is not satisfied
|
||||
}
|
13
tests/ui/trait-bounds/issue-119530-sugg-from-fn.stderr
Normal file
13
tests/ui/trait-bounds/issue-119530-sugg-from-fn.stderr
Normal file
@ -0,0 +1,13 @@
|
||||
error[E0277]: the trait bound `String: Copy` is not satisfied
|
||||
--> $DIR/issue-119530-sugg-from-fn.rs:4:23
|
||||
|
|
||||
LL | let string_arr = [foo(); 64];
|
||||
| ^^^^^ the trait `Copy` is not implemented for `String`
|
||||
|
|
||||
= note: the `Copy` trait is required because this value will be copied for each element of the array
|
||||
= help: consider using `core::array::from_fn` to initialize the array
|
||||
= help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -231,6 +231,31 @@ fn infcx() {
|
||||
let _cx: cx::cx::Cx = cx::cx::cx::cx::cx::Cx;
|
||||
}
|
||||
|
||||
fn return_already() -> impl std::fmt::Debug {
|
||||
loop {
|
||||
return !!!!!!!
|
||||
break !!!!!!1111
|
||||
}
|
||||
}
|
||||
|
||||
fn fake_macros() -> impl std::fmt::Debug {
|
||||
loop {
|
||||
if! {
|
||||
match! (
|
||||
break! {
|
||||
return! {
|
||||
1337
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
{}
|
||||
}
|
||||
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
strange();
|
||||
funny();
|
||||
@ -257,4 +282,6 @@ pub fn main() {
|
||||
semisemisemisemisemi();
|
||||
useful_syntax();
|
||||
infcx();
|
||||
return_already();
|
||||
fake_macros();
|
||||
}
|
||||
|
@ -643,6 +643,7 @@ compiler-team = [
|
||||
"@compiler-errors",
|
||||
"@petrochenkov",
|
||||
"@davidtwco",
|
||||
"@estebank",
|
||||
"@oli-obk",
|
||||
"@wesleywiser",
|
||||
]
|
||||
@ -693,18 +694,21 @@ incremental = [
|
||||
diagnostics = [
|
||||
"@compiler-errors",
|
||||
"@davidtwco",
|
||||
"@estebank",
|
||||
"@oli-obk",
|
||||
"@TaKO8Ki",
|
||||
]
|
||||
parser = [
|
||||
"@compiler-errors",
|
||||
"@davidtwco",
|
||||
"@estebank",
|
||||
"@nnethercote",
|
||||
"@petrochenkov",
|
||||
]
|
||||
lexer = [
|
||||
"@nnethercote",
|
||||
"@petrochenkov",
|
||||
"@estebank",
|
||||
]
|
||||
arena = [
|
||||
"@nnethercote",
|
||||
@ -731,6 +735,7 @@ borrowck = [
|
||||
]
|
||||
ast_lowering = [
|
||||
"@compiler-errors",
|
||||
"@estebank",
|
||||
"@spastorino",
|
||||
]
|
||||
fallback = [
|
||||
|
Loading…
Reference in New Issue
Block a user