"rustc-demangle",
]
+[[package]]
+name = "base16ct"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce"
+
+[[package]]
+name = "base64ct"
+version = "1.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf"
+
[[package]]
name = "bitflags"
version = "1.3.2"
"toml",
]
+[[package]]
+name = "bumpalo"
+version = "3.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
+
[[package]]
name = "bytecount"
version = "0.6.2"
"opener",
"openssl",
"os_info",
+ "pasetors",
"pathdiff",
"percent-encoding",
"pretty_env_logger",
"tar",
"tempfile",
"termcolor",
+ "time 0.3.17",
"toml_edit",
"unicode-width",
"unicode-xid",
"glob",
"itertools",
"lazy_static",
+ "pasetors",
+ "serde",
"serde_json",
"snapbox",
"tar",
"termcolor",
+ "time 0.3.17",
"toml_edit",
"url",
"winapi",
"num-integer",
"num-traits",
"serde",
- "time",
+ "time 0.1.43",
"winapi",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317"
+[[package]]
+name = "const-oid"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b"
+
[[package]]
name = "content_inspector"
version = "0.2.4"
[[package]]
name = "crates-io"
-version = "0.35.0"
+version = "0.35.1"
dependencies = [
"anyhow",
"curl",
"cfg-if",
]
+[[package]]
+name = "crypto-bigint"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef"
+dependencies = [
+ "generic-array",
+ "rand_core 0.6.4",
+ "subtle",
+ "zeroize",
+]
+
[[package]]
name = "crypto-common"
-version = "0.1.2"
+version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
+ "typenum",
]
[[package]]
"quote",
]
+[[package]]
+name = "ct-codecs"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df"
+
[[package]]
name = "ctor"
version = "0.1.26"
"syn",
]
+[[package]]
+name = "der"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de"
+dependencies = [
+ "const-oid",
+ "pem-rfc7468",
+ "zeroize",
+]
+
[[package]]
name = "derive-new"
version = "0.5.8"
[[package]]
name = "digest"
-version = "0.10.2"
+version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837"
+checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
dependencies = [
"block-buffer",
"crypto-common",
+ "subtle",
]
[[package]]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541"
+[[package]]
+name = "ecdsa"
+version = "0.14.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c"
+dependencies = [
+ "der",
+ "elliptic-curve",
+ "rfc6979",
+ "signature",
+]
+
+[[package]]
+name = "ed25519-compact"
+version = "2.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a3d382e8464107391c8706b4c14b087808ecb909f6c15c34114bc42e53a9e4c"
+dependencies = [
+ "getrandom 0.2.8",
+]
+
[[package]]
name = "either"
version = "1.6.0"
"serde_json",
]
+[[package]]
+name = "elliptic-curve"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3"
+dependencies = [
+ "base16ct",
+ "crypto-bigint",
+ "der",
+ "digest",
+ "ff",
+ "generic-array",
+ "group",
+ "hkdf",
+ "pem-rfc7468",
+ "pkcs8",
+ "rand_core 0.6.4",
+ "sec1",
+ "subtle",
+ "zeroize",
+]
+
[[package]]
name = "ena"
version = "0.14.0"
"instant",
]
+[[package]]
+name = "ff"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160"
+dependencies = [
+ "rand_core 0.6.4",
+ "subtle",
+]
+
+[[package]]
+name = "fiat-crypto"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90"
+
[[package]]
name = "filetime"
version = "0.2.14"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
+ "js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
+ "wasm-bindgen",
]
[[package]]
"regex",
]
+[[package]]
+name = "group"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7"
+dependencies = [
+ "ff",
+ "rand_core 0.6.4",
+ "subtle",
+]
+
[[package]]
name = "gsgdt"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
+[[package]]
+name = "hkdf"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437"
+dependencies = [
+ "hmac",
+]
+
+[[package]]
+name = "hmac"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest",
+]
+
[[package]]
name = "home"
version = "0.5.3"
checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe"
dependencies = [
"bitmaps",
- "rand_core 0.6.2",
+ "rand_core 0.6.4",
"rand_xoshiro",
"sized-chunks",
"typenum",
"libc",
]
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
[[package]]
name = "jsondocck"
version = "0.1.0"
"num-traits",
]
+[[package]]
+name = "orion"
+version = "0.17.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2baf7fd2e326e3895c681176788dd227fcd8369350e53c570592d8563fecbb6"
+dependencies = [
+ "fiat-crypto",
+ "subtle",
+ "zeroize",
+]
+
[[package]]
name = "os_info"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
+[[package]]
+name = "p384"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa"
+dependencies = [
+ "ecdsa",
+ "elliptic-curve",
+ "sha2",
+]
+
[[package]]
name = "packed_simd_2"
version = "0.3.8"
"windows-sys",
]
+[[package]]
+name = "pasetors"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed20c4c21d893414f42e0cbfebe8a8036b5ae9b0264611fb6504e395eda6ceec"
+dependencies = [
+ "ct-codecs",
+ "ed25519-compact",
+ "getrandom 0.2.8",
+ "orion",
+ "p384",
+ "rand_core 0.6.4",
+ "regex",
+ "serde",
+ "serde_json",
+ "sha2",
+ "subtle",
+ "time 0.3.17",
+ "zeroize",
+]
+
[[package]]
name = "pathdiff"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+[[package]]
+name = "pem-rfc7468"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac"
+dependencies = [
+ "base64ct",
+]
+
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+[[package]]
+name = "pkcs8"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba"
+dependencies = [
+ "der",
+ "spki",
+]
+
[[package]]
name = "pkg-config"
version = "0.3.25"
dependencies = [
"libc",
"rand_chacha 0.3.0",
- "rand_core 0.6.2",
+ "rand_core 0.6.4",
]
[[package]]
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
dependencies = [
"ppv-lite86",
- "rand_core 0.6.2",
+ "rand_core 0.6.4",
]
[[package]]
[[package]]
name = "rand_core"
-version = "0.6.2"
+version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.8",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
dependencies = [
- "rand_core 0.6.2",
+ "rand_core 0.6.4",
]
[[package]]
"walkdir",
]
+[[package]]
+name = "rfc6979"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb"
+dependencies = [
+ "crypto-bigint",
+ "hmac",
+ "zeroize",
+]
+
[[package]]
name = "rls"
version = "2.0.0"
dependencies = [
"bstr 0.2.17",
"clap 3.2.20",
+ "getrandom 0.2.8",
"libc",
"libz-sys",
"rand 0.8.5",
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+[[package]]
+name = "sec1"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928"
+dependencies = [
+ "base16ct",
+ "der",
+ "generic-array",
+ "pkcs8",
+ "subtle",
+ "zeroize",
+]
+
[[package]]
name = "security-framework"
version = "2.0.0"
[[package]]
name = "sha2"
-version = "0.10.1"
+version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec"
+checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
dependencies = [
"cfg-if",
"cpufeatures",
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
+[[package]]
+name = "signature"
+version = "1.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
+dependencies = [
+ "digest",
+ "rand_core 0.6.4",
+]
+
[[package]]
name = "similar"
version = "2.1.0"
"uuid",
]
+[[package]]
+name = "spki"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b"
+dependencies = [
+ "base64ct",
+ "der",
+]
+
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
"syn",
]
+[[package]]
+name = "subtle"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
+
[[package]]
name = "syn"
version = "1.0.107"
"winapi",
]
+[[package]]
+name = "time"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
+dependencies = [
+ "itoa",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
+
+[[package]]
+name = "time-macros"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
+dependencies = [
+ "time-core",
+]
+
[[package]]
name = "tinystr"
version = "0.7.0"
[[package]]
name = "typenum"
-version = "1.12.0"
+version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
+checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "ucd-parse"
"rustc-std-workspace-core",
]
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
[[package]]
name = "winapi"
version = "0.3.9"
"synstructure",
]
+[[package]]
+name = "zeroize"
+version = "1.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"
+
[[package]]
name = "zerovec"
version = "0.9.0"
Ok(())
}
Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
- write!(f, "{{{}:{}}}", operand_idx, modifier)
+ write!(f, "{{{operand_idx}:{modifier}}}")
}
Self::Placeholder { operand_idx, modifier: None, .. } => {
- write!(f, "{{{}}}", operand_idx)
+ write!(f, "{{{operand_idx}}}")
}
}
}
use fmt::Write;
let mut out = String::new();
for p in s.iter() {
- let _ = write!(out, "{}", p);
+ let _ = write!(out, "{p}");
}
out
}
match &self.kind {
AttrKind::Normal(normal) => normal.tokens.as_ref(),
kind @ AttrKind::DocComment(..) => {
- panic!("Called tokens on doc comment attr {:?}", kind)
+ panic!("Called tokens on doc comment attr {kind:?}")
}
}
}
Some(match &mut self.kind {
AttrKind::Normal(normal) => &mut normal.tokens,
kind @ AttrKind::DocComment(..) => {
- panic!("Called tokens_mut on doc comment attr {:?}", kind)
+ panic!("Called tokens_mut on doc comment attr {kind:?}")
}
})
}
AttrKind::Normal(normal) => normal
.tokens
.as_ref()
- .unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self))
+ .unwrap_or_else(|| panic!("attribute is missing tokens: {self:?}"))
.to_attr_token_stream()
.to_tokenstream(),
&AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token(
impl AllocatorKind {
pub fn fn_name(&self, base: Symbol) -> String {
match *self {
- AllocatorKind::Global => format!("__rg_{}", base),
- AllocatorKind::Default => format!("__rdl_{}", base),
+ AllocatorKind::Global => format!("__rg_{base}"),
+ AllocatorKind::Default => format!("__rdl_{base}"),
}
}
}
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Lit { kind, symbol, suffix } = *self;
match kind {
- Byte => write!(f, "b'{}'", symbol)?,
- Char => write!(f, "'{}'", symbol)?,
- Str => write!(f, "\"{}\"", symbol)?,
+ Byte => write!(f, "b'{symbol}'")?,
+ Char => write!(f, "'{symbol}'")?,
+ Str => write!(f, "\"{symbol}\"")?,
StrRaw(n) => write!(
f,
"r{delim}\"{string}\"{delim}",
delim = "#".repeat(n as usize),
string = symbol
)?,
- ByteStr => write!(f, "b\"{}\"", symbol)?,
+ ByteStr => write!(f, "b\"{symbol}\"")?,
ByteStrRaw(n) => write!(
f,
"br{delim}\"{string}\"{delim}",
delim = "#".repeat(n as usize),
string = symbol
)?,
- Integer | Float | Bool | Err => write!(f, "{}", symbol)?,
+ Integer | Float | Bool | Err => write!(f, "{symbol}")?,
}
if let Some(suffix) = suffix {
- write!(f, "{}", suffix)?;
+ write!(f, "{suffix}")?;
}
Ok(())
_ => return None,
},
SingleQuote => match joint.kind {
- Ident(name, false) => Lifetime(Symbol::intern(&format!("'{}", name))),
+ Ident(name, false) => Lifetime(Symbol::intern(&format!("'{name}"))),
_ => return None,
},
assert!(
found,
- "Failed to find trailing delimited group in: {:?}",
- target_tokens
+ "Failed to find trailing delimited group in: {target_tokens:?}"
);
}
let mut flat: SmallVec<[_; 1]> = SmallVec::new();
match *self {
LitKind::Byte(b) => {
let b: String = ascii::escape_default(b).map(Into::<char>::into).collect();
- write!(f, "b'{}'", b)?;
+ write!(f, "b'{b}'")?;
}
LitKind::Char(ch) => write!(f, "'{}'", escape_char_symbol(ch))?,
LitKind::Str(sym, StrStyle::Cooked) => write!(f, "\"{}\"", escape_string_symbol(sym))?,
)?;
}
LitKind::Int(n, ty) => {
- write!(f, "{}", n)?;
+ write!(f, "{n}")?;
match ty {
ast::LitIntType::Unsigned(ty) => write!(f, "{}", ty.name())?,
ast::LitIntType::Signed(ty) => write!(f, "{}", ty.name())?,
}
}
LitKind::Float(symbol, ty) => {
- write!(f, "{}", symbol)?;
+ write!(f, "{symbol}")?;
match ty {
ast::LitFloatType::Suffixed(ty) => write!(f, "{}", ty.name())?,
ast::LitFloatType::Unsuffixed => {}
Err(supported_abis) => {
let mut abis = format!("`{}`", supported_abis[0]);
for m in &supported_abis[1..] {
- let _ = write!(abis, ", `{}`", m);
+ let _ = write!(abis, ", `{m}`");
}
self.tcx.sess.emit_err(InvalidAbiClobberAbi {
abi_span: *abi_span,
let sub = if !valid_modifiers.is_empty() {
let mut mods = format!("`{}`", valid_modifiers[0]);
for m in &valid_modifiers[1..] {
- let _ = write!(mods, ", `{}`", m);
+ let _ = write!(mods, ", `{m}`");
}
InvalidAsmTemplateModifierRegClassSub::SupportModifier {
class_name: class.name(),
}
_ => {
// Replace the ident for bindings that aren't simple.
- let name = format!("__arg{}", index);
+ let name = format!("__arg{index}");
let ident = Ident::from_str(&name);
(ident, false)
ImplTraitPosition::ImplReturn => "`impl` method return",
};
- write!(f, "{}", name)
+ write!(f, "{name}")
}
}
fn orig_local_def_id(&self, node: NodeId) -> LocalDefId {
self.orig_opt_local_def_id(node)
- .unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node))
+ .unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
}
/// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
}
fn local_def_id(&self, node: NodeId) -> LocalDefId {
- self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node))
+ self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
}
/// Get the previously recorded `to` local def id given the `from` local def id, obtained using
fn lower_trait_ref(&mut self, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> {
let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
hir::QPath::Resolved(None, path) => path,
- qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
+ qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
};
hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
}
data: Symbol,
) -> String {
match (comment_kind, attr_style) {
- (CommentKind::Line, ast::AttrStyle::Outer) => format!("///{}", data),
- (CommentKind::Line, ast::AttrStyle::Inner) => format!("//!{}", data),
- (CommentKind::Block, ast::AttrStyle::Outer) => format!("/**{}*/", data),
- (CommentKind::Block, ast::AttrStyle::Inner) => format!("/*!{}*/", data),
+ (CommentKind::Line, ast::AttrStyle::Outer) => format!("///{data}"),
+ (CommentKind::Line, ast::AttrStyle::Inner) => format!("//!{data}"),
+ (CommentKind::Block, ast::AttrStyle::Outer) => format!("/**{data}*/"),
+ (CommentKind::Block, ast::AttrStyle::Inner) => format!("/*!{data}*/"),
}
}
pub fn literal_to_string(lit: token::Lit) -> String {
let token::Lit { kind, symbol, suffix } = lit;
let mut out = match kind {
- token::Byte => format!("b'{}'", symbol),
- token::Char => format!("'{}'", symbol),
- token::Str => format!("\"{}\"", symbol),
+ token::Byte => format!("b'{symbol}'"),
+ token::Char => format!("'{symbol}'"),
+ token::Str => format!("\"{symbol}\""),
token::StrRaw(n) => {
format!("r{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = symbol)
}
- token::ByteStr => format!("b\"{}\"", symbol),
+ token::ByteStr => format!("b\"{symbol}\""),
token::ByteStrRaw(n) => {
format!("br{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = symbol)
}
ast::VisibilityKind::Restricted { path, shorthand, .. } => {
let path = Self::to_string(|s| s.print_path(path, false, 0));
if *shorthand && (path == "crate" || path == "self" || path == "super") {
- self.word_nbsp(format!("pub({})", path))
+ self.word_nbsp(format!("pub({path})"))
} else {
- self.word_nbsp(format!("pub(in {})", path))
+ self.word_nbsp(format!("pub(in {path})"))
}
}
ast::VisibilityKind::Inherited => {}
fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &Features) {
let (cfg, feature, has_feature) = gated_cfg;
if !has_feature(features) && !cfg_span.allows_unstable(*feature) {
- let explain = format!("`cfg({})` is experimental and subject to change", cfg);
+ let explain = format!("`cfg({cfg})` is experimental and subject to change");
feature_err(sess, *feature, cfg_span, &explain).emit();
}
}
}
pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
- assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {:?}", attr);
+ assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}");
use ReprAttr::*;
let mut acc = Vec::new();
let diagnostic = &sess.parse_sess.span_diagnostic;
// Manual implementation to be able to format `expected` items correctly.
impl<'a> IntoDiagnostic<'a> for UnknownMetaItem<'_> {
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
- let expected = self.expected.iter().map(|name| format!("`{}`", name)).collect::<Vec<_>>();
+ let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
let mut diag = handler.struct_span_err_with_code(
self.span,
fluent::attr_unknown_meta_item,
}
}
let typeck = self.infcx.tcx.typeck(self.mir_def_id());
- let hir_id = hir.get_parent_node(expr.hir_id);
+ let hir_id = hir.parent_id(expr.hir_id);
if let Some(parent) = hir.find(hir_id) {
let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
let hir = self.infcx.tcx.hir();
let closure_id = self.mir_hir_id();
let closure_span = self.infcx.tcx.def_span(self.mir_def_id());
- let fn_call_id = hir.get_parent_node(closure_id);
+ let fn_call_id = hir.parent_id(closure_id);
let node = hir.get(fn_call_id);
let def_id = hir.enclosing_body_owner(fn_call_id);
let mut look_at_return = true;
/// local place can be mutated.
//
// FIXME: @nikomatsakis suggested that this flag could be removed with the following modifications:
-// - Merge `check_access_permissions()` and `check_if_reassignment_to_immutable_state()`.
// - Split `is_mutable()` into `is_assignable()` (can be directly assigned) and
// `is_declared_mutable()`.
// - Take flow state into consideration in `is_assignable()` for local variables.
// Write of P[i] or *P requires P init'd.
self.check_if_assigned_path_is_moved(location, place_span, flow_state);
- // Special case: you can assign an immutable local variable
- // (e.g., `x = ...`) so long as it has never been initialized
- // before (at this point in the flow).
- if let Some(local) = place_span.0.as_local() {
- if let Mutability::Not = self.body.local_decls[local].mutability {
- // check for reassignments to immutable local variables
- self.check_if_reassignment_to_immutable_state(
- location, local, place_span, flow_state,
- );
- return;
- }
- }
-
- // Otherwise, use the normal access permission rules.
self.access_place(
location,
place_span,
}
}
- fn check_if_reassignment_to_immutable_state(
- &mut self,
- location: Location,
- local: Local,
- place_span: (Place<'tcx>, Span),
- flow_state: &Flows<'cx, 'tcx>,
- ) {
- debug!("check_if_reassignment_to_immutable_state({:?})", local);
-
- // Check if any of the initializations of `local` have happened yet:
- if let Some(init_index) = self.is_local_ever_initialized(local, flow_state) {
- // And, if so, report an error.
- let init = &self.move_data.inits[init_index];
- let span = init.span(&self.body);
- self.report_illegal_reassignment(location, place_span, span, place_span.0);
- }
- }
-
fn check_if_full_path_is_moved(
&mut self,
location: Location,
// partial initialization, do not complain about mutability
// errors except for actual mutation (as opposed to an attempt
// to do a partial initialization).
- let previously_initialized =
- self.is_local_ever_initialized(place.local, flow_state).is_some();
+ let previously_initialized = self.is_local_ever_initialized(place.local, flow_state);
// at this point, we have set up the error reporting state.
- if previously_initialized {
- self.report_mutability_error(place, span, the_place_err, error_access, location);
+ if let Some(init_index) = previously_initialized {
+ if let (AccessKind::Mutate, Some(_)) = (error_access, place.as_local()) {
+ // If this is a mutate access to an immutable local variable with no projections
+ // report the error as an illegal reassignment
+ let init = &self.move_data.inits[init_index];
+ let assigned_span = init.span(&self.body);
+ self.report_illegal_reassignment(location, (place, span), assigned_span, place);
+ } else {
+ self.report_mutability_error(place, span, the_place_err, error_access, location)
+ }
true
} else {
false
use rustc_metadata::fs::{emit_wrapper_file, METADATA_FILENAME};
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
-use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Lto, Strip};
+use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind};
use rustc_session::cstore::DllImport;
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
Ok(())
}
+// Crate type is not passed when calculating the dylibs to include for LTO. In that case all
+// crate types must use the same dependency formats.
pub fn each_linked_rlib(
- sess: &Session,
info: &CrateInfo,
+ crate_type: Option<CrateType>,
f: &mut dyn FnMut(CrateNum, &Path),
) -> Result<(), errors::LinkRlibError> {
let crates = info.used_crates.iter();
- let mut fmts = None;
- let lto_active = matches!(sess.lto(), Lto::Fat | Lto::Thin);
- if lto_active {
+ let fmts = if crate_type.is_none() {
for combination in info.dependency_formats.iter().combinations(2) {
let (ty1, list1) = &combination[0];
let (ty2, list2) = &combination[1];
});
}
}
- }
-
- for (ty, list) in info.dependency_formats.iter() {
- match ty {
- CrateType::Executable
- | CrateType::Staticlib
- | CrateType::Cdylib
- | CrateType::ProcMacro => {
- fmts = Some(list);
- break;
- }
- CrateType::Dylib if lto_active => {
- fmts = Some(list);
- break;
- }
- _ => {}
+ if info.dependency_formats.is_empty() {
+ return Err(errors::LinkRlibError::MissingFormat);
}
- }
- let Some(fmts) = fmts else {
- return Err(errors::LinkRlibError::MissingFormat);
+ &info.dependency_formats[0].1
+ } else {
+ let fmts = info
+ .dependency_formats
+ .iter()
+ .find_map(|&(ty, ref list)| if Some(ty) == crate_type { Some(list) } else { None });
+
+ let Some(fmts) = fmts else {
+ return Err(errors::LinkRlibError::MissingFormat);
+ };
+
+ fmts
};
+
for &cnum in crates {
match fmts.get(cnum.as_usize() - 1) {
Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue,
)?;
let mut all_native_libs = vec![];
- let res = each_linked_rlib(sess, &codegen_results.crate_info, &mut |cnum, path| {
- let name = codegen_results.crate_info.crate_name[&cnum];
- let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
-
- // Here when we include the rlib into our staticlib we need to make a
- // decision whether to include the extra object files along the way.
- // These extra object files come from statically included native
- // libraries, but they may be cfg'd away with #[link(cfg(..))].
- //
- // This unstable feature, though, only needs liblibc to work. The only
- // use case there is where musl is statically included in liblibc.rlib,
- // so if we don't want the included version we just need to skip it. As
- // a result the logic here is that if *any* linked library is cfg'd away
- // we just skip all object files.
- //
- // Clearly this is not sufficient for a general purpose feature, and
- // we'd want to read from the library's metadata to determine which
- // object files come from where and selectively skip them.
- let skip_object_files = native_libs.iter().any(|lib| {
- matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
- && !relevant_lib(sess, lib)
- });
+ let res = each_linked_rlib(
+ &codegen_results.crate_info,
+ Some(CrateType::Staticlib),
+ &mut |cnum, path| {
+ let name = codegen_results.crate_info.crate_name[&cnum];
+ let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
+
+ // Here when we include the rlib into our staticlib we need to make a
+ // decision whether to include the extra object files along the way.
+ // These extra object files come from statically included native
+ // libraries, but they may be cfg'd away with #[link(cfg(..))].
+ //
+ // This unstable feature, though, only needs liblibc to work. The only
+ // use case there is where musl is statically included in liblibc.rlib,
+ // so if we don't want the included version we just need to skip it. As
+ // a result the logic here is that if *any* linked library is cfg'd away
+ // we just skip all object files.
+ //
+ // Clearly this is not sufficient for a general purpose feature, and
+ // we'd want to read from the library's metadata to determine which
+ // object files come from where and selectively skip them.
+ let skip_object_files = native_libs.iter().any(|lib| {
+ matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
+ && !relevant_lib(sess, lib)
+ });
- let lto = are_upstream_rust_objects_already_included(sess)
- && !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
+ let lto = are_upstream_rust_objects_already_included(sess)
+ && !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
- // Ignoring obj file starting with the crate name
- // as simple comparison is not enough - there
- // might be also an extra name suffix
- let obj_start = name.as_str().to_owned();
+ // Ignoring obj file starting with the crate name
+ // as simple comparison is not enough - there
+ // might be also an extra name suffix
+ let obj_start = name.as_str().to_owned();
- ab.add_archive(
- path,
- Box::new(move |fname: &str| {
- // Ignore metadata files, no matter the name.
- if fname == METADATA_FILENAME {
- return true;
- }
+ ab.add_archive(
+ path,
+ Box::new(move |fname: &str| {
+ // Ignore metadata files, no matter the name.
+ if fname == METADATA_FILENAME {
+ return true;
+ }
- // Don't include Rust objects if LTO is enabled
- if lto && looks_like_rust_object_file(fname) {
- return true;
- }
+ // Don't include Rust objects if LTO is enabled
+ if lto && looks_like_rust_object_file(fname) {
+ return true;
+ }
- // Otherwise if this is *not* a rust object and we're skipping
- // objects then skip this file
- if skip_object_files && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) {
- return true;
- }
+ // Otherwise if this is *not* a rust object and we're skipping
+ // objects then skip this file
+ if skip_object_files
+ && (!fname.starts_with(&obj_start) || !fname.ends_with(".o"))
+ {
+ return true;
+ }
- // ok, don't skip this
- false
- }),
- )
- .unwrap();
+ // ok, don't skip this
+ false
+ }),
+ )
+ .unwrap();
- all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
- });
+ all_native_libs
+ .extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
+ },
+ );
if let Err(e) = res {
sess.emit_fatal(e);
}
if !lib_args.is_empty() {
sess.emit_note(errors::StaticLibraryNativeArtifacts);
// Prefix for greppability
- sess.emit_note(errors::NativeStaticLibs { arguments: lib_args.join(" ") });
+ // Note: This must not be translated as tools are allowed to depend on this exact string.
+ sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" ")));
}
}
let sess = tcx.sess;
let mut each_linked_rlib_for_lto = Vec::new();
- drop(link::each_linked_rlib(sess, crate_info, &mut |cnum, path| {
+ drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| {
if link::ignored_for_lto(sess, crate_info, cnum) {
return;
}
#[diag(codegen_ssa_static_library_native_artifacts)]
pub struct StaticLibraryNativeArtifacts;
-#[derive(Diagnostic)]
-#[diag(codegen_ssa_native_static_libs)]
-pub struct NativeStaticLibs {
- pub arguments: String,
-}
-
#[derive(Diagnostic)]
#[diag(codegen_ssa_link_script_unavailable)]
pub struct LinkScriptUnavailable;
let local_def_id = def_id.expect_local();
let hir_id = tcx.local_def_id_to_hir_id(local_def_id);
- let Some(parent) = tcx.hir().find_parent_node(hir_id) else { return false };
+ let Some(parent) = tcx.hir().opt_parent_id(hir_id) else { return false };
let parent_def = tcx.hir().get(parent);
if !matches!(
}
pub fn immediate_dominator(&self, node: Node) -> Node {
- assert!(self.is_reachable(node), "node {:?} is not reachable", node);
+ assert!(self.is_reachable(node), "node {node:?} is not reachable");
self.immediate_dominators[node].unwrap()
}
pub fn dominators(&self, node: Node) -> Iter<'_, Node> {
- assert!(self.is_reachable(node), "node {:?} is not reachable", node);
+ assert!(self.is_reachable(node), "node {node:?} is not reachable");
Iter { dominators: self, node: Some(node) }
}
.map(G::Node::new)
.map(|node| match this.start_walk_from(node) {
WalkReturn::Complete { scc_index } => scc_index,
- WalkReturn::Cycle { min_depth } => panic!(
- "`start_walk_node({:?})` returned cycle with depth {:?}",
- node, min_depth
- ),
+ WalkReturn::Cycle { min_depth } => {
+ panic!("`start_walk_node({node:?})` returned cycle with depth {min_depth:?}")
+ }
})
.collect();
NodeState::NotVisited => return None,
NodeState::InCycleWith { parent } => panic!(
- "`find_state` returned `InCycleWith({:?})`, which ought to be impossible",
- parent
+ "`find_state` returned `InCycleWith({parent:?})`, which ought to be impossible"
),
})
}
previous_node = previous;
}
// Only InCycleWith nodes were added to the reverse linked list.
- other => panic!("Invalid previous link while compressing cycle: {:?}", other),
+ other => panic!("Invalid previous link while compressing cycle: {other:?}"),
}
debug!("find_state: parent_state = {:?}", node_state);
// NotVisited can not be part of a cycle since it should
// have instead gotten explored.
NodeState::NotVisited | NodeState::InCycleWith { .. } => {
- panic!("invalid parent state: {:?}", node_state)
+ panic!("invalid parent state: {node_state:?}")
}
}
}
let counter = COUNTER.fetch_add(1, Ordering::AcqRel);
- let file_path = dir.as_ref().join(format!("{:010}_{}.gv", counter, description));
+ let file_path = dir.as_ref().join(format!("{counter:010}_{description}.gv"));
let mut gv_file = BufWriter::new(File::create(file_path).unwrap());
}
fn node_id(&self, index: &Self::Node) -> dot::Id<'_> {
- dot::Id::new(format!("obligation_{}", index)).unwrap()
+ dot::Id::new(format!("obligation_{index}")).unwrap()
}
fn node_label(&self, index: &Self::Node) -> dot::LabelText<'_> {
// length can behave as a source of entropy for heap addresses, when
// ASLR is disabled and the heap is otherwise determinic.
let pid: u32 = process::id();
- let filename = format!("{}-{:07}.rustc_profile", crate_name, pid);
+ let filename = format!("{crate_name}-{pid:07}.rustc_profile");
let path = output_directory.join(&filename);
let profiler =
Profiler::with_counter(&path, measureme::counters::Counter::by_name(counter_name)?)?;
SmallVec::from_vec(data)
};
if let Err(e) = ffi::CStr::from_bytes_with_nul(&data) {
- panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e);
+ panic!("The string \"{s}\" cannot be converted into a CStr: {e}");
}
SmallCStr { data }
}
pub fn new_with_nul(s: &str) -> SmallCStr {
let b = s.as_bytes();
if let Err(e) = ffi::CStr::from_bytes_with_nul(b) {
- panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e);
+ panic!("The string \"{s}\" cannot be converted into a CStr: {e}");
}
SmallCStr { data: SmallVec::from_slice(s.as_bytes()) }
}
iter.into_iter().flat_map(|s| s.as_bytes()).copied().collect::<SmallVec<_>>();
data.push(0);
if let Err(e) = ffi::CStr::from_bytes_with_nul(&data) {
- panic!("The iterator {:?} cannot be converted into a CStr: {}", data, e);
+ panic!("The iterator {data:?} cannot be converted into a CStr: {e}");
}
Self { data }
}
// This should return just one element, otherwise it's a bug
assert!(
filter.next().is_none(),
- "Collection {:#?} should have just one matching element",
- self
+ "Collection {self:#?} should have just one matching element"
);
Some(value)
}
Ok(arg) => args.extend(arg),
Err(err) => rustc_session::early_error(
rustc_session::config::ErrorOutputType::default(),
- &format!("Failed to load argument file: {}", err),
+ &format!("Failed to load argument file: {err}"),
),
}
}
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Utf8Error(None) => write!(fmt, "Utf8 error"),
- Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {}", path),
- Error::IOError(path, err) => write!(fmt, "IO Error: {}: {}", path, err),
+ Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {path}"),
+ Error::IOError(path, err) => write!(fmt, "IO Error: {path}: {err}"),
}
}
}
fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
let upper_cased_code = code.to_ascii_uppercase();
- let normalised = if upper_cased_code.starts_with('E') {
- upper_cased_code
- } else {
- format!("E{0:0>4}", code)
- };
+ let normalised =
+ if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") };
match registry.try_find_description(&normalised) {
Ok(Some(description)) => {
let mut is_in_code_block = false;
if io::stdout().is_terminal() {
show_content_with_pager(&text);
} else {
- print!("{}", text);
+ print!("{text}");
}
}
Ok(None) => {
- early_error(output, &format!("no extended information for {}", code));
+ early_error(output, &format!("no extended information for {code}"));
}
Err(InvalidErrorCode) => {
- early_error(output, &format!("{} is not a valid error code", code));
+ early_error(output, &format!("{code} is not a valid error code"));
}
}
}
// If pager fails for whatever reason, we should still print the content
// to standard output
if fallback_to_println {
- print!("{}", content);
+ print!("{content}");
}
}
);
let id = rustc_session::output::find_crate_name(sess, attrs, input);
if *req == PrintRequest::CrateName {
- println!("{}", id);
+ println!("{id}");
continue;
}
let crate_types = collect_crate_types(sess, attrs);
}
if let Some(value) = value {
- Some(format!("{}=\"{}\"", name, value))
+ Some(format!("{name}=\"{value}\""))
} else {
Some(name.to_string())
}
cfgs.sort();
for cfg in cfgs {
- println!("{}", cfg);
+ println!("{cfg}");
}
}
CallingConventions => {
let stable = sess.target.options.supported_split_debuginfo.contains(split);
let unstable_ok = sess.unstable_options();
if stable || unstable_ok {
- println!("{}", split);
+ println!("{split}");
}
}
}
) {
let verbose = matches.opt_present("verbose");
- println!("{} {}", binary, version);
+ println!("{binary} {version}");
if verbose {
- println!("binary: {}", binary);
- println!("commit-hash: {}", commit_hash);
- println!("commit-date: {}", commit_date);
+ println!("binary: {binary}");
+ println!("commit-hash: {commit_hash}");
+ println!("commit-date: {commit_date}");
println!("host: {}", config::host_triple());
- println!("release: {}", release);
+ println!("release: {release}");
let debug_flags = matches.opt_strs("Z");
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
.map(|&(name, ..)| ('C', name))
.chain(Z_OPTIONS.iter().map(|&(name, ..)| ('Z', name)))
.find(|&(_, name)| *opt == name.replace('_', "-"))
- .map(|(flag, _)| format!("{}. Did you mean `-{} {}`?", e, flag, opt)),
+ .map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")),
_ => None,
};
early_error(ErrorOutputType::default(), &msg.unwrap_or_else(|| e.to_string()));
} else {
result.push(a.to_string());
match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| option == **s) {
- Some(s) => result.push(format!("{}=[REDACTED]", s)),
+ Some(s) => result.push(format!("{s}=[REDACTED]")),
None => result.push(content),
}
}
let mut xs: Vec<Cow<'static, str>> = vec![
"the compiler unexpectedly panicked. this is a bug.".into(),
- format!("we would appreciate a bug report: {}", bug_report_url).into(),
+ format!("we would appreciate a bug report: {bug_report_url}").into(),
format!(
"rustc {} running on {}",
util::version_str!().unwrap_or("unknown_version"),
arg.into_string().unwrap_or_else(|arg| {
early_error(
ErrorOutputType::default(),
- &format!("argument {} is not valid Unicode: {:?}", i, arg),
+ &format!("argument {i} is not valid Unicode: {arg:?}"),
)
})
})
fn write_or_print(out: &str, ofile: Option<&Path>, sess: &Session) {
match ofile {
- None => print!("{}", out),
+ None => print!("{out}"),
Some(p) => {
if let Err(e) = std::fs::write(p, out) {
sess.emit_fatal(UnprettyDumpFail {
}
AstTree(PpAstTreeMode::Normal) => {
debug!("pretty printing AST tree");
- format!("{:#?}", krate)
+ format!("{krate:#?}")
}
_ => unreachable!(),
};
AstTree(PpAstTreeMode::Expanded) => {
debug!("pretty-printing expanded AST");
- format!("{:#?}", krate)
+ format!("{krate:#?}")
}
Hir(s) => call_with_pp_support_hir(&s, tcx, move |annotation, hir_map| {
codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
-codegen_ssa_native_static_libs = native-static-libs: {$arguments}
-
codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker
codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error}
}
impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
+ type Failure = (Token, usize, &'static str);
+
+ fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure {
+ (tok, position, msg)
+ }
+
fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc) {
if self.remaining_matcher.is_none()
|| (parser.has_no_remaining_items_for_step() && *matcher != MatcherLoc::Eof)
}
}
- fn after_arm(&mut self, result: &NamedParseResult) {
+ fn after_arm(&mut self, result: &NamedParseResult<Self::Failure>) {
match result {
Success(_) => {
// Nonterminal parser recovery might turn failed matches into successful ones,
"should not collect detailed info for successful macro match",
);
}
- Failure(token, approx_position, msg) => {
+ Failure((token, approx_position, msg)) => {
debug!(?token, ?msg, "a new failure of an arm");
if self
}
}
+/// Currently used by macro_rules! compilation to extract a little information from the `Failure` case.
+pub struct FailureForwarder;
+
+impl<'matcher> Tracker<'matcher> for FailureForwarder {
+ type Failure = (Token, usize, &'static str);
+
+ fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure {
+ (tok, position, msg)
+ }
+
+ fn description() -> &'static str {
+ "failure-forwarder"
+ }
+}
+
pub(super) fn emit_frag_parse_err(
mut e: DiagnosticBuilder<'_, rustc_errors::ErrorGuaranteed>,
parser: &Parser<'_>,
}
/// Represents the possible results of an attempted parse.
-pub(crate) enum ParseResult<T> {
+pub(crate) enum ParseResult<T, F> {
/// Parsed successfully.
Success(T),
/// Arm failed to match. If the second parameter is `token::Eof`, it indicates an unexpected
/// end of macro invocation. Otherwise, it indicates that no rules expected the given token.
/// The usize is the approximate position of the token in the input token stream.
- Failure(Token, usize, &'static str),
+ Failure(F),
/// Fatal error (malformed macro?). Abort compilation.
Error(rustc_span::Span, String),
ErrorReported(ErrorGuaranteed),
/// A `ParseResult` where the `Success` variant contains a mapping of
/// `MacroRulesNormalizedIdent`s to `NamedMatch`es. This represents the mapping
/// of metavars to the token trees they bind to.
-pub(crate) type NamedParseResult = ParseResult<NamedMatches>;
+pub(crate) type NamedParseResult<F> = ParseResult<NamedMatches, F>;
/// Contains a mapping of `MacroRulesNormalizedIdent`s to `NamedMatch`es.
/// This represents the mapping of metavars to the token trees they bind to.
token: &Token,
approx_position: usize,
track: &mut T,
- ) -> Option<NamedParseResult> {
+ ) -> Option<NamedParseResult<T::Failure>> {
// Matcher positions that would be valid if the macro invocation was over now. Only
// modified if `token == Eof`.
let mut eof_mps = EofMatcherPositions::None;
EofMatcherPositions::Multiple => {
Error(token.span, "ambiguity: multiple successful parses".to_string())
}
- EofMatcherPositions::None => Failure(
+ EofMatcherPositions::None => Failure(T::build_failure(
Token::new(
token::Eof,
if token.span.is_dummy() { token.span } else { token.span.shrink_to_hi() },
),
approx_position,
"missing tokens in macro arguments",
- ),
+ )),
})
} else {
None
parser: &mut Cow<'_, Parser<'_>>,
matcher: &'matcher [MatcherLoc],
track: &mut T,
- ) -> NamedParseResult {
+ ) -> NamedParseResult<T::Failure> {
// A queue of possible matcher positions. We initialize it with the matcher position in
// which the "dot" is before the first token of the first token tree in `matcher`.
// `parse_tt_inner` then processes all of these possible matcher positions and produces
(0, 0) => {
// There are no possible next positions AND we aren't waiting for the black-box
// parser: syntax error.
- return Failure(
+ return Failure(T::build_failure(
parser.token.clone(),
parser.approx_token_stream_pos(),
"no rules expected this token in macro call",
- );
+ ));
}
(_, 0) => {
}
}
- fn ambiguity_error(
+ fn ambiguity_error<F>(
&self,
matcher: &[MatcherLoc],
token_span: rustc_span::Span,
- ) -> NamedParseResult {
+ ) -> NamedParseResult<F> {
let nts = self
.bb_mps
.iter()
)
}
- fn nameize<I: Iterator<Item = NamedMatch>>(
+ fn nameize<I: Iterator<Item = NamedMatch>, F>(
&self,
matcher: &[MatcherLoc],
mut res: I,
- ) -> NamedParseResult {
+ ) -> NamedParseResult<F> {
// Make that each metavar has _exactly one_ binding. If so, insert the binding into the
// `NamedParseResult`. Otherwise, it's an error.
let mut ret_val = FxHashMap::default();
}
pub(super) trait Tracker<'matcher> {
+ /// The contents of `ParseResult::Failure`.
+ type Failure;
+
+ /// Arm failed to match. If the token is `token::Eof`, it indicates an unexpected
+ /// end of macro invocation. Otherwise, it indicates that no rules expected the given token.
+ /// The usize is the approximate position of the token in the input token stream.
+ fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure;
+
/// This is called before trying to match next MatcherLoc on the current token.
- fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc);
+ fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {}
/// This is called after an arm has been parsed, either successfully or unsuccessfully. When this is called,
/// `before_match_loc` was called at least once (with a `MatcherLoc::Eof`).
- fn after_arm(&mut self, result: &NamedParseResult);
+ fn after_arm(&mut self, _result: &NamedParseResult<Self::Failure>) {}
/// For tracing.
fn description() -> &'static str;
- fn recovery() -> Recovery;
+ fn recovery() -> Recovery {
+ Recovery::Forbidden
+ }
}
/// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization.
pub(super) struct NoopTracker;
impl<'matcher> Tracker<'matcher> for NoopTracker {
- fn before_match_loc(&mut self, _: &TtParser, _: &'matcher MatcherLoc) {}
- fn after_arm(&mut self, _: &NamedParseResult) {}
+ type Failure = ();
+
+ fn build_failure(_tok: Token, _position: usize, _msg: &'static str) -> Self::Failure {}
+
fn description() -> &'static str {
"none"
}
- fn recovery() -> Recovery {
- Recovery::Forbidden
- }
}
/// Expands the rules based macro defined by `lhses` and `rhses` for a given
return Ok((i, named_matches));
}
- Failure(_, reached_position, _) => {
- trace!(%reached_position, "Failed to match arm, trying the next one");
+ Failure(_) => {
+ trace!("Failed to match arm, trying the next one");
// Try the next arm.
}
Error(_, _) => {
let rhs_nm = Ident::new(sym::rhs, def.span);
let tt_spec = Some(NonterminalKind::TT);
- // Parse the macro_rules! invocation
- let (macro_rules, body) = match &def.kind {
- ast::ItemKind::MacroDef(def) => (def.macro_rules, def.body.tokens.clone()),
+ let macro_def = match &def.kind {
+ ast::ItemKind::MacroDef(def) => def,
_ => unreachable!(),
};
+ let macro_rules = macro_def.macro_rules;
+
+ // Parse the macro_rules! invocation
// The pattern that macro_rules matches.
// The grammar for macro_rules! is:
// Convert it into `MatcherLoc` form.
let argument_gram = mbe::macro_parser::compute_locs(&argument_gram);
- let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS);
+ let create_parser = || {
+ let body = macro_def.body.tokens.clone();
+ Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS)
+ };
+
+ let parser = create_parser();
let mut tt_parser =
TtParser::new(Ident::with_dummy_span(if macro_rules { kw::MacroRules } else { kw::Macro }));
let argument_map =
match tt_parser.parse_tt(&mut Cow::Owned(parser), &argument_gram, &mut NoopTracker) {
Success(m) => m,
- Failure(token, _, msg) => {
+ Failure(()) => {
+ // The fast `NoopTracker` doesn't have any info on failure, so we need to retry it with another one
+ // that gives us the information we need.
+ // For this we need to reclone the macro body as the previous parser consumed it.
+ let retry_parser = create_parser();
+
+ let parse_result = tt_parser.parse_tt(
+ &mut Cow::Owned(retry_parser),
+ &argument_gram,
+ &mut diagnostics::FailureForwarder,
+ );
+ let Failure((token, _, msg)) = parse_result else {
+ unreachable!("matcher returned something other than Failure after retry");
+ };
+
let s = parse_failure_msg(&token);
let sp = token.span.substitute_dummy(def.span);
let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s);
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
Self::Gated(ref stab, name, expl, _) => {
- write!(fmt, "Gated({:?}, {}, {})", stab, name, expl)
+ write!(fmt, "Gated({stab:?}, {name}, {expl})")
}
Self::Ungated => write!(fmt, "Ungated"),
}
.find(|t| t.name == feature);
match found {
Some(found) => found.issue,
- None => panic!("feature `{}` is not declared anywhere", feature),
+ None => panic!("feature `{feature}` is not declared anywhere"),
}
}
}
match *self {
LabelStr(ref s) => format!("\"{}\"", s.escape_default()),
EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(s)),
- HtmlStr(ref s) => format!("<{}>", s),
+ HtmlStr(ref s) => format!("<{s}>"),
}
}
if let Some(fontname) = options.iter().find_map(|option| {
if let RenderOption::Fontname(fontname) = option { Some(fontname) } else { None }
}) {
- font = format!(r#"fontname="{}""#, fontname);
+ font = format!(r#"fontname="{fontname}""#);
graph_attrs.push(&font[..]);
content_attrs.push(&font[..]);
}
if !(graph_attrs.is_empty() && content_attrs.is_empty()) {
writeln!(w, r#" graph[{}];"#, graph_attrs.join(" "))?;
let content_attrs_str = content_attrs.join(" ");
- writeln!(w, r#" node[{}];"#, content_attrs_str)?;
- writeln!(w, r#" edge[{}];"#, content_attrs_str)?;
+ writeln!(w, r#" node[{content_attrs_str}];"#)?;
+ writeln!(w, r#" edge[{content_attrs_str}];"#)?;
}
let mut text = Vec::new();
write!(text, "{}", id.as_slice()).unwrap();
if !options.contains(&RenderOption::NoNodeLabels) {
- write!(text, "[label={}]", escaped).unwrap();
+ write!(text, "[label={escaped}]").unwrap();
}
let style = g.node_style(n);
write!(text, "{} -> {}", source_id.as_slice(), target_id.as_slice()).unwrap();
if !options.contains(&RenderOption::NoEdgeLabels) {
- write!(text, "[label={}]", escaped_label).unwrap();
+ write!(text, "[label={escaped_label}]").unwrap();
}
let style = g.edge_style(e);
where
Id: Debug,
{
- self.opt_def_id()
- .unwrap_or_else(|| panic!("attempted .def_id() on invalid res: {:?}", self))
+ self.opt_def_id().unwrap_or_else(|| panic!("attempted .def_id() on invalid res: {self:?}"))
}
/// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.
//
// See the documentation for DefPathHash for more information.
panic!(
- "found DefPathHash collision between {:?} and {:?}. \
- Compilation cannot continue.",
- def_path1, def_path2
+ "found DefPathHash collision between {def_path1:?} and {def_path2:?}. \
+ Compilation cannot continue."
);
}
let mut s = String::with_capacity(self.data.len() * 16);
for component in &self.data {
- write!(s, "::{}", component).unwrap();
+ write!(s, "::{component}").unwrap();
}
s
for component in &self.data {
s.extend(opt_delimiter);
opt_delimiter = Some('-');
- write!(s, "{}", component).unwrap();
+ write!(s, "{component}").unwrap();
}
s
match self.name() {
DefPathDataName::Named(name) => f.write_str(name.as_str()),
// FIXME(#70334): this will generate legacy {{closure}}, {{impl}}, etc
- DefPathDataName::Anon { namespace } => write!(f, "{{{{{}}}}}", namespace),
+ DefPathDataName::Anon { namespace } => write!(f, "{{{{{namespace}}}}}"),
}
}
}
/// ```ignore (illustrative)
/// ctor
/// .ctor_hir_id()
- /// .and_then(|ctor_id| tcx.hir().find(tcx.hir().get_parent_node(ctor_id)))
+ /// .and_then(|ctor_id| tcx.hir().find_parent(ctor_id))
/// .and_then(|parent| parent.ident())
/// ```
pub fn ident(&self) -> Option<Ident> {
impl fmt::Display for HirId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{:?}", self)
+ write!(f, "{self:?}")
}
}
let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
hir.get(fn_hir_id) else { return None };
let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(i), .. }) =
- hir.get(hir.get_parent_node(fn_hir_id)) else { bug!("ImplItem should have Impl parent") };
+ hir.get_parent(fn_hir_id) else { bug!("ImplItem should have Impl parent") };
let trait_ref = self.instantiate_mono_trait_ref(
i.of_trait.as_ref()?,
is_fn = true;
// Check if parent is const or static
- let parent_id = tcx.hir().get_parent_node(hir_ty.hir_id);
+ let parent_id = tcx.hir().parent_id(hir_ty.hir_id);
let parent_node = tcx.hir().get(parent_id);
is_const_or_static = matches!(
ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => {
// Do not try to infer the return type for a impl method coming from a trait
if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) =
- tcx.hir().get(tcx.hir().get_parent_node(hir_id))
+ tcx.hir().get_parent(hir_id)
&& i.of_trait.is_some()
{
<dyn AstConv<'_>>::ty_of_fn(
// `min_const_generics`.
Some(parent_def_id.to_def_id())
} else {
- let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
+ let parent_node = tcx.hir().get_parent(hir_id);
match parent_node {
// HACK(eddyb) this provides the correct generics for repeat
// expressions' count (i.e. `N` in `[x; N]`), and explicit
// provide junk type parameter defs for const blocks.
if let Node::AnonConst(_) = node {
- let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
+ let parent_node = tcx.hir().get_parent(hir_id);
if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node {
params.push(ty::GenericParamDef {
index: next_index(),
};
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
// Ensure that the parent of the def is an item, not HRTB
- let parent_id = self.tcx.hir().get_parent_node(hir_id);
+ let parent_id = self.tcx.hir().parent_id(hir_id);
if !parent_id.is_owner() {
struct_span_err!(
self.tcx.sess,
// We create bi-directional Outlives predicates between the original
// and the duplicated parameter, to ensure that they do not get out of sync.
if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
- let opaque_ty_id = tcx.hir().get_parent_node(hir_id);
+ let opaque_ty_id = tcx.hir().parent_id(hir_id);
let opaque_ty_node = tcx.hir().get(opaque_ty_id);
let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else {
bug!("unexpected {opaque_ty_node:?}")
_ => return None,
};
- let parent_node_id = tcx.hir().get_parent_node(hir_id);
+ let parent_node_id = tcx.hir().parent_id(hir_id);
let parent_node = tcx.hir().get(parent_node_id);
let (generics, arg_idx) = match parent_node {
}
Node::AnonConst(_) => {
- let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
+ let parent_node = tcx.hir().get_parent(hir_id);
match parent_node {
Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. })
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
..
},
) if let Node::TraitRef(trait_ref) =
- tcx.hir().get(tcx.hir().get_parent_node(binding_id))
+ tcx.hir().get_parent(binding_id)
&& e.hir_id == hir_id =>
{
let Some(trait_def_id) = trait_ref.trait_def_id() else {
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))
+ tcx.hir().get_parent(binding_id)
&& let Some((idx, _)) =
gen_args.args.iter().enumerate().find(|(_, arg)| {
if let GenericArg::Const(ct) = arg {
num = num_trait_generics_except_self,
);
- if let Some(parent_node) = self.tcx.hir().find_parent_node(self.path_segment.hir_id)
+ if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id)
&& let Some(parent_node) = self.tcx.hir().find(parent_node)
&& let hir::Node::Expr(expr) = parent_node {
match expr.kind {
hir::InlineAsmOperand::In { reg, ref expr } => {
s.word("in");
s.popen();
- s.word(format!("{}", reg));
+ s.word(format!("{reg}"));
s.pclose();
s.space();
s.print_expr(expr);
hir::InlineAsmOperand::Out { reg, late, ref expr } => {
s.word(if late { "lateout" } else { "out" });
s.popen();
- s.word(format!("{}", reg));
+ s.word(format!("{reg}"));
s.pclose();
s.space();
match expr {
hir::InlineAsmOperand::InOut { reg, late, ref expr } => {
s.word(if late { "inlateout" } else { "inout" });
s.popen();
- s.word(format!("{}", reg));
+ s.word(format!("{reg}"));
s.pclose();
s.space();
s.print_expr(expr);
hir::InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
s.word(if late { "inlateout" } else { "inout" });
s.popen();
- s.word(format!("{}", reg));
+ s.word(format!("{reg}"));
s.pclose();
s.space();
s.print_expr(in_expr);
fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, sp: Span) -> Option<(Span, String)> {
let node = {
- let rslt = self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(hir_id));
+ let rslt = self.tcx.hir().parent_id(self.tcx.hir().parent_id(hir_id));
self.tcx.hir().get(rslt)
};
if let hir::Node::Block(block) = node {
// check that the body's parent is an fn
- let parent = self
- .tcx
- .hir()
- .get(self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(block.hir_id)));
+ let parent = self.tcx.hir().get_parent(self.tcx.hir().parent_id(block.hir_id));
if let (Some(expr), hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. })) =
(&block.expr, parent)
{
None
}
})?;
- let opaque_ty = self.tcx.mk_opaque(rpit_def_id, substs);
if !self.can_coerce(first_ty, expected) || !self.can_coerce(second_ty, expected) {
return None;
{
let pred = pred.kind().rebind(match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) => {
- assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);
+ // FIXME(rpitit): This will need to be fixed when we move to associated types
+ assert!(matches!(
+ *trait_pred.trait_ref.self_ty().kind(),
+ ty::Alias(_, ty::AliasTy { def_id, substs, .. })
+ if def_id == rpit_def_id && substs == substs
+ ));
ty::PredicateKind::Clause(ty::Clause::Trait(
trait_pred.with_self_ty(self.tcx, ty),
))
}
ty::PredicateKind::Clause(ty::Clause::Projection(mut proj_pred)) => {
- assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty);
+ assert!(matches!(
+ *proj_pred.projection_ty.self_ty().kind(),
+ ty::Alias(_, ty::AliasTy { def_id, substs, .. })
+ if def_id == rpit_def_id && substs == substs
+ ));
proj_pred = proj_pred.with_self_ty(self.tcx, ty);
ty::PredicateKind::Clause(ty::Clause::Projection(proj_pred))
}
callee_span: Span,
) {
let hir = self.tcx.hir();
- let parent_hir_id = hir.get_parent_node(hir_id);
+ let parent_hir_id = hir.parent_id(hir_id);
let parent_node = hir.get(parent_hir_id);
if let (
hir::Node::Expr(hir::Expr {
{
// Actually need to unwrap a few more layers of HIR to get to
// the _real_ closure...
- let async_closure = hir.get_parent_node(hir.get_parent_node(parent_hir_id));
+ let async_closure = hir.parent_id(hir.parent_id(parent_hir_id));
if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
..
call_expr: &'tcx hir::Expr<'tcx>,
callee_expr: &'tcx hir::Expr<'tcx>,
) -> bool {
- let hir_id = self.tcx.hir().get_parent_node(call_expr.hir_id);
+ let hir_id = self.tcx.hir().parent_id(call_expr.hir_id);
let parent_node = self.tcx.hir().get(hir_id);
if let (
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Array(_), .. }),
use rustc_macros::{TypeFoldable, TypeVisitable};
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::{self, Ty, TypeSuperVisitable, TypeVisitor};
use rustc_span::source_map::Span;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use std::cmp;
use std::iter;
+use std::ops::ControlFlow;
/// What signature do we *expect* the closure to have from context?
#[derive(Debug, Clone, TypeFoldable, TypeVisitable)]
// closure sooner rather than later, so first examine the expected
// type, and see if can glean a closure kind from there.
let (expected_sig, expected_kind) = match expected.to_option(self) {
- Some(ty) => self.deduce_expectations_from_expected_type(ty),
+ Some(ty) => self.deduce_closure_signature(ty),
None => (None, None),
};
let body = self.tcx.hir().body(closure.body);
/// Given the expected type, figures out what it can about this closure we
/// are about to type check:
#[instrument(skip(self), level = "debug")]
- fn deduce_expectations_from_expected_type(
+ fn deduce_closure_signature(
&self,
expected_ty: Ty<'tcx>,
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
match *expected_ty.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => self
- .deduce_signature_from_predicates(
+ .deduce_closure_signature_from_predicates(
+ expected_ty,
self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs),
),
ty::Dynamic(ref object_type, ..) => {
.and_then(|did| self.tcx.fn_trait_kind_from_def_id(did));
(sig, kind)
}
- ty::Infer(ty::TyVar(vid)) => self.deduce_signature_from_predicates(
+ ty::Infer(ty::TyVar(vid)) => self.deduce_closure_signature_from_predicates(
+ self.tcx.mk_ty_var(self.root_var(vid)),
self.obligations_for_self_ty(vid).map(|obl| (obl.predicate, obl.cause.span)),
),
ty::FnPtr(sig) => {
}
}
- fn deduce_signature_from_predicates(
+ fn deduce_closure_signature_from_predicates(
&self,
+ expected_ty: Ty<'tcx>,
predicates: impl DoubleEndedIterator<Item = (ty::Predicate<'tcx>, Span)>,
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
let mut expected_sig = None;
if expected_sig.is_none()
&& let ty::PredicateKind::Clause(ty::Clause::Projection(proj_predicate)) = bound_predicate.skip_binder()
{
- expected_sig = self.normalize(
+ let inferred_sig = self.normalize(
obligation.cause.span,
self.deduce_sig_from_projection(
Some(obligation.cause.span),
bound_predicate.rebind(proj_predicate),
),
);
+ // Make sure that we didn't infer a signature that mentions itself.
+ // This can happen when we elaborate certain supertrait bounds that
+ // mention projections containing the `Self` type. See #105401.
+ struct MentionsTy<'tcx> {
+ expected_ty: Ty<'tcx>,
+ }
+ impl<'tcx> TypeVisitor<'tcx> for MentionsTy<'tcx> {
+ type BreakTy = ();
+
+ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+ if t == self.expected_ty {
+ ControlFlow::BREAK
+ } else {
+ t.super_visit_with(self)
+ }
+ }
+ }
+ if inferred_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() {
+ expected_sig = inferred_sig;
+ }
}
// Even if we can't infer the full signature, we may be able to
err.span_label(cause.span, "return type is not `()`");
}
ObligationCauseCode::BlockTailExpression(blk_id) => {
- let parent_id = fcx.tcx.hir().get_parent_node(blk_id);
+ let parent_id = fcx.tcx.hir().parent_id(blk_id);
err = self.report_return_mismatched_types(
cause,
expected,
None,
);
if !fcx.tcx.features().unsized_locals {
- let id = fcx.tcx.hir().get_parent_node(id);
+ let id = fcx.tcx.hir().parent_id(id);
unsized_return = self.is_return_ty_unsized(fcx, id);
}
}
let mut pointing_at_return_type = false;
let mut fn_output = None;
- let parent_id = fcx.tcx.hir().get_parent_node(id);
+ let parent_id = fcx.tcx.hir().parent_id(id);
let parent = fcx.tcx.hir().get(parent_id);
if let Some(expr) = expression
&& let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { body, .. }), .. }) = parent
use crate::FnCtxt;
use rustc_ast::util::parser::PREC_POSTFIX;
+use rustc_data_structures::fx::FxHashMap;
use rustc_errors::MultiSpan;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def::CtorKind;
+use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{is_range_literal, Node};
use rustc_infer::infer::InferOk;
use rustc_middle::middle::stability::EvalResult;
use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut};
+use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder};
+use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
+use rustc_middle::ty::relate::TypeRelation;
+use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitable};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{BytePos, Span};
use rustc_trait_selection::infer::InferCtxtExt as _;
+use rustc_trait_selection::traits::error_reporting::method_chain::CollectAllMismatches;
use rustc_trait_selection::traits::ObligationCause;
use super::method::probe;
self.annotate_alternative_method_deref(err, expr, error);
// Use `||` to give these suggestions a precedence
- let _ = self.suggest_missing_parentheses(err, expr)
+ let suggested = self.suggest_missing_parentheses(err, expr)
|| self.suggest_remove_last_method_call(err, expr, expected)
|| self.suggest_associated_const(err, expr, expected)
|| self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
|| self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
|| self.suggest_into(err, expr, expr_ty, expected)
|| self.suggest_floating_point_literal(err, expr, expected);
+ if !suggested {
+ self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected);
+ }
}
pub fn emit_coerce_suggestions(
(expected, Some(err))
}
+ pub fn point_at_expr_source_of_inferred_type(
+ &self,
+ err: &mut Diagnostic,
+ expr: &hir::Expr<'_>,
+ found: Ty<'tcx>,
+ expected: Ty<'tcx>,
+ ) -> bool {
+ let map = self.tcx.hir();
+
+ let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind else { return false; };
+ let [hir::PathSegment { ident, args: None, .. }] = p.segments else { return false; };
+ let hir::def::Res::Local(hir_id) = p.res else { return false; };
+ let Some(hir::Node::Pat(pat)) = map.find(hir_id) else { return false; };
+ let Some(hir::Node::Local(hir::Local {
+ ty: None,
+ init: Some(init),
+ ..
+ })) = map.find_parent(pat.hir_id) else { return false; };
+ let Some(ty) = self.node_ty_opt(init.hir_id) else { return false; };
+ if ty.is_closure() || init.span.overlaps(expr.span) || pat.span.from_expansion() {
+ return false;
+ }
+
+ // Locate all the usages of the relevant binding.
+ struct FindExprs<'hir> {
+ hir_id: hir::HirId,
+ uses: Vec<&'hir hir::Expr<'hir>>,
+ }
+ impl<'v> Visitor<'v> for FindExprs<'v> {
+ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
+ if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = ex.kind
+ && let hir::def::Res::Local(hir_id) = path.res
+ && hir_id == self.hir_id
+ {
+ self.uses.push(ex);
+ }
+ hir::intravisit::walk_expr(self, ex);
+ }
+ }
+
+ let mut expr_finder = FindExprs { hir_id, uses: vec![] };
+ let id = map.get_parent_item(hir_id);
+ let hir_id: hir::HirId = id.into();
+
+ let Some(node) = map.find(hir_id) else { return false; };
+ let Some(body_id) = node.body_id() else { return false; };
+ let body = map.body(body_id);
+ expr_finder.visit_expr(body.value);
+ // Hack to make equality checks on types with inference variables and regions useful.
+ let mut eraser = BottomUpFolder {
+ tcx: self.tcx,
+ lt_op: |_| self.tcx.lifetimes.re_erased,
+ ct_op: |c| c,
+ ty_op: |t| match *t.kind() {
+ ty::Infer(ty::TyVar(vid)) => self.tcx.mk_ty_infer(ty::TyVar(self.root_var(vid))),
+ ty::Infer(ty::IntVar(_)) => {
+ self.tcx.mk_ty_infer(ty::IntVar(ty::IntVid { index: 0 }))
+ }
+ ty::Infer(ty::FloatVar(_)) => {
+ self.tcx.mk_ty_infer(ty::FloatVar(ty::FloatVid { index: 0 }))
+ }
+ _ => t,
+ },
+ };
+ let mut prev = eraser.fold_ty(ty);
+ let mut prev_span = None;
+
+ for binding in expr_finder.uses {
+ // In every expression where the binding is referenced, we will look at that
+ // expression's type and see if it is where the incorrect found type was fully
+ // "materialized" and point at it. We will also try to provide a suggestion there.
+ if let Some(hir::Node::Expr(expr)
+ | hir::Node::Stmt(hir::Stmt {
+ kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr),
+ ..
+ })) = &map.find_parent(binding.hir_id)
+ && let hir::ExprKind::MethodCall(segment, rcvr, args, _span) = expr.kind
+ && rcvr.hir_id == binding.hir_id
+ && let Some(def_id) = self.typeck_results.borrow().type_dependent_def_id(expr.hir_id)
+ {
+ // We special case methods, because they can influence inference through the
+ // call's arguments and we can provide a more explicit span.
+ let sig = self.tcx.fn_sig(def_id);
+ let def_self_ty = sig.input(0).skip_binder();
+ let rcvr_ty = self.node_ty(rcvr.hir_id);
+ // Get the evaluated type *after* calling the method call, so that the influence
+ // of the arguments can be reflected in the receiver type. The receiver
+ // expression has the type *before* theis analysis is done.
+ let ty = match self.lookup_probe(
+ segment.ident,
+ rcvr_ty,
+ expr,
+ probe::ProbeScope::TraitsInScope,
+ ) {
+ Ok(pick) => pick.self_ty,
+ Err(_) => rcvr_ty,
+ };
+ // Remove one layer of references to account for `&mut self` and
+ // `&self`, so that we can compare it against the binding.
+ let (ty, def_self_ty) = match (ty.kind(), def_self_ty.kind()) {
+ (ty::Ref(_, ty, a), ty::Ref(_, self_ty, b)) if a == b => (*ty, *self_ty),
+ _ => (ty, def_self_ty),
+ };
+ let mut param_args = FxHashMap::default();
+ let mut param_expected = FxHashMap::default();
+ let mut param_found = FxHashMap::default();
+ if self.can_eq(self.param_env, ty, found).is_ok() {
+ // We only point at the first place where the found type was inferred.
+ for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() {
+ if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() {
+ // We found an argument that references a type parameter in `Self`,
+ // so we assume that this is the argument that caused the found
+ // type, which we know already because of `can_eq` above was first
+ // inferred in this method call.
+ let arg = &args[i];
+ let arg_ty = self.node_ty(arg.hir_id);
+ err.span_label(
+ arg.span,
+ &format!(
+ "this is of type `{arg_ty}`, which causes `{ident}` to be \
+ inferred as `{ty}`",
+ ),
+ );
+ param_args.insert(param_ty, (arg, arg_ty));
+ }
+ }
+ }
+
+ // Here we find, for a type param `T`, the type that `T` is in the current
+ // method call *and* in the original expected type. That way, we can see if we
+ // can give any structured suggestion for the function argument.
+ let mut c = CollectAllMismatches {
+ infcx: &self.infcx,
+ param_env: self.param_env,
+ errors: vec![],
+ };
+ let _ = c.relate(def_self_ty, ty);
+ for error in c.errors {
+ if let TypeError::Sorts(error) = error {
+ param_found.insert(error.expected, error.found);
+ }
+ }
+ c.errors = vec![];
+ let _ = c.relate(def_self_ty, expected);
+ for error in c.errors {
+ if let TypeError::Sorts(error) = error {
+ param_expected.insert(error.expected, error.found);
+ }
+ }
+ for (param, (arg, arg_ty)) in param_args.iter() {
+ let Some(expected) = param_expected.get(param) else { continue; };
+ let Some(found) = param_found.get(param) else { continue; };
+ if self.can_eq(self.param_env, *arg_ty, *found).is_err() { continue; }
+ self.emit_coerce_suggestions(err, arg, *found, *expected, None, None);
+ }
+
+ let ty = eraser.fold_ty(ty);
+ if ty.references_error() {
+ break;
+ }
+ if ty != prev
+ && param_args.is_empty()
+ && self.can_eq(self.param_env, ty, found).is_ok()
+ {
+ // We only point at the first place where the found type was inferred.
+ err.span_label(
+ segment.ident.span,
+ with_forced_trimmed_paths!(format!(
+ "here the type of `{ident}` is inferred to be `{ty}`",
+ )),
+ );
+ break;
+ } else if !param_args.is_empty() {
+ break;
+ }
+ prev = ty;
+ } else {
+ let ty = eraser.fold_ty(self.node_ty(binding.hir_id));
+ if ty.references_error() {
+ break;
+ }
+ if ty != prev
+ && let Some(span) = prev_span
+ && self.can_eq(self.param_env, ty, found).is_ok()
+ {
+ // We only point at the first place where the found type was inferred.
+ // We use the *previous* span because if the type is known *here* it means
+ // it was *evaluated earlier*. We don't do this for method calls because we
+ // evaluate the method's self type eagerly, but not in any other case.
+ err.span_label(
+ span,
+ with_forced_trimmed_paths!(format!(
+ "here the type of `{ident}` is inferred to be `{ty}`",
+ )),
+ );
+ break;
+ }
+ prev = ty;
+ }
+ if binding.hir_id == expr.hir_id {
+ // Do not look at expressions that come after the expression we were originally
+ // evaluating and had a type error.
+ break;
+ }
+ prev_span = Some(binding.span);
+ }
+ true
+ }
+
fn annotate_expected_due_to_let_ty(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
error: Option<TypeError<'tcx>>,
) {
- let parent = self.tcx.hir().get_parent_node(expr.hir_id);
+ let parent = self.tcx.hir().parent_id(expr.hir_id);
match (self.tcx.hir().find(parent), error) {
(Some(hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. })), _)
if init.hir_id == expr.hir_id =>
hir::Path { res: hir::def::Res::Local(hir_id), .. },
)) => {
if let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(*hir_id) {
- let parent = self.tcx.hir().get_parent_node(pat.hir_id);
primary_span = pat.span;
secondary_span = pat.span;
- match self.tcx.hir().find(parent) {
+ match self.tcx.hir().find_parent(pat.hir_id) {
Some(hir::Node::Local(hir::Local { ty: Some(ty), .. })) => {
primary_span = ty.span;
post_message = " type";
expr: &hir::Expr<'_>,
error: Option<TypeError<'tcx>>,
) {
- let parent = self.tcx.hir().get_parent_node(expr.hir_id);
+ let parent = self.tcx.hir().parent_id(expr.hir_id);
let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else {return;};
let Some(hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Assign(lhs, rhs, _), ..
// Unroll desugaring, to make sure this works for `for` loops etc.
loop {
- parent = self.tcx.hir().get_parent_node(id);
+ parent = self.tcx.hir().parent_id(id);
if let Some(parent_span) = self.tcx.hir().opt_span(parent) {
if parent_span.find_ancestor_inside(expr.span).is_some() {
// The parent node is part of the same span, so is the result of the
return None;
};
- let local_parent = self.tcx.hir().get_parent_node(local_id);
+ let local_parent = self.tcx.hir().parent_id(local_id);
let Some(Node::Param(hir::Param { hir_id: param_hir_id, .. })) = self.tcx.hir().find(local_parent) else {
return None;
};
- let param_parent = self.tcx.hir().get_parent_node(*param_hir_id);
+ let param_parent = self.tcx.hir().parent_id(*param_hir_id);
let Some(Node::Expr(hir::Expr {
hir_id: expr_hir_id,
kind: hir::ExprKind::Closure(hir::Closure { fn_decl: closure_fn_decl, .. }),
return None;
};
- let expr_parent = self.tcx.hir().get_parent_node(*expr_hir_id);
+ let expr_parent = self.tcx.hir().parent_id(*expr_hir_id);
let hir = self.tcx.hir().find(expr_parent);
let closure_params_len = closure_fn_decl.inputs.len();
let (
_ => None,
}?;
- match hir.find(hir.get_parent_node(expr.hir_id))? {
+ match hir.find_parent(expr.hir_id)? {
Node::ExprField(field) => {
if field.ident.name == local.name && field.is_shorthand {
return Some(local.name);
/// Returns whether the given expression is an `else if`.
pub(crate) fn is_else_if_block(&self, expr: &hir::Expr<'_>) -> bool {
if let hir::ExprKind::If(..) = expr.kind {
- let parent_id = self.tcx.hir().get_parent_node(expr.hir_id);
+ let parent_id = self.tcx.hir().parent_id(expr.hir_id);
if let Some(Node::Expr(hir::Expr {
kind: hir::ExprKind::If(_, _, Some(else_expr)),
..
if let Some(hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Assign(..),
..
- })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id))
+ })) = self.tcx.hir().find_parent(expr.hir_id)
{
if mutability.is_mut() {
// Suppressing this diagnostic, we'll properly print it in `check_expr_assign`
let mut sugg = vec![];
- if let Some(hir::Node::ExprField(field)) =
- self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id))
- {
+ if let Some(hir::Node::ExprField(field)) = self.tcx.hir().find_parent(expr.hir_id) {
// `expr` is a literal field for a struct, only suggest if appropriate
if field.is_shorthand {
// This is a field literal
[start, end],
_,
) = expr.kind else { return; };
- let parent = self.tcx.hir().get_parent_node(expr.hir_id);
+ let parent = self.tcx.hir().parent_id(expr.hir_id);
if let Some(hir::Node::ExprField(_)) = self.tcx.hir().find(parent) {
// Ignore `Foo { field: a..Default::default() }`
return;
) => self.check_expr_path(qpath, expr, args),
_ => self.check_expr_kind(expr, expected),
});
+ let ty = self.resolve_vars_if_possible(ty);
// Warn for non-block expressions with diverging children.
match expr.kind {
original_expr_id: HirId,
then: impl FnOnce(&hir::Expr<'_>),
) {
- let mut parent = self.tcx.hir().get_parent_node(original_expr_id);
+ let mut parent = self.tcx.hir().parent_id(original_expr_id);
while let Some(node) = self.tcx.hir().find(parent) {
match node {
hir::Node::Expr(hir::Expr {
}) => {
// Check if our original expression is a child of the condition of a while loop
let expr_is_ancestor = std::iter::successors(Some(original_expr_id), |id| {
- self.tcx.hir().find_parent_node(*id)
+ self.tcx.hir().opt_parent_id(*id)
})
.take_while(|id| *id != parent)
.any(|id| id == expr.hir_id);
| hir::Node::TraitItem(_)
| hir::Node::Crate(_) => break,
_ => {
- parent = self.tcx.hir().get_parent_node(parent);
+ parent = self.tcx.hir().parent_id(parent);
}
}
}
// Do not suggest `if let x = y` as `==` is way more likely to be the intention.
let hir = self.tcx.hir();
if let hir::Node::Expr(hir::Expr { kind: ExprKind::If { .. }, .. }) =
- hir.get(hir.get_parent_node(hir.get_parent_node(expr.hir_id)))
+ hir.get_parent(hir.parent_id(expr.hir_id))
{
err.span_suggestion_verbose(
expr.span.shrink_to_lo(),
err.span_label(field.span, "method, not a field");
let expr_is_call =
if let hir::Node::Expr(hir::Expr { kind: ExprKind::Call(callee, _args), .. }) =
- self.tcx.hir().get(self.tcx.hir().get_parent_node(expr.hir_id))
+ self.tcx.hir().get_parent(expr.hir_id)
{
expr.hir_id == callee.hir_id
} else {
pub(in super::super) fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
let mut contained_in_place = false;
- while let hir::Node::Expr(parent_expr) =
- self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
- {
+ while let hir::Node::Expr(parent_expr) = self.tcx.hir().get_parent(expr_id) {
match &parent_expr.kind {
hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
if lhs.hir_id == expr_id {
call_expr: &hir::Expr<'tcx>,
) {
// Next, let's construct the error
- let (error_span, full_call_span, ctor_of, is_method) = match &call_expr.kind {
+ let (error_span, full_call_span, call_name, is_method) = match &call_expr.kind {
hir::ExprKind::Call(
hir::Expr { hir_id, span, kind: hir::ExprKind::Path(qpath), .. },
_,
if let Res::Def(DefKind::Ctor(of, _), _) =
self.typeck_results.borrow().qpath_res(qpath, *hir_id)
{
- (call_span, *span, Some(of), false)
+ let name = match of {
+ CtorOf::Struct => "struct",
+ CtorOf::Variant => "enum variant",
+ };
+ (call_span, *span, name, false)
} else {
- (call_span, *span, None, false)
+ (call_span, *span, "function", false)
}
}
- hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None, false),
+ hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, "function", false),
hir::ExprKind::MethodCall(path_segment, _, _, span) => {
let ident_span = path_segment.ident.span;
let ident_span = if let Some(args) = path_segment.args {
} else {
ident_span
};
- // methods are never ctors
- (*span, ident_span, None, true)
+ (*span, ident_span, "method", true)
}
k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
};
let args_span = error_span.trim_start(full_call_span).unwrap_or(error_span);
- let call_name = match ctor_of {
- Some(CtorOf::Struct) => "struct",
- Some(CtorOf::Variant) => "enum variant",
- None => "function",
- };
// Don't print if it has error types or is just plain `_`
fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
err = tcx.sess.struct_span_err_with_code(
full_call_span,
&format!(
- "this {} takes {}{} but {} {} supplied",
- call_name,
+ "{call_name} takes {}{} but {} {} supplied",
if c_variadic { "at least " } else { "" },
potentially_plural_count(
formal_and_expected_inputs.len(),
full_call_span,
format!("arguments to this {} are incorrect", call_name),
);
+ if let (Some(callee_ty), hir::ExprKind::MethodCall(_, rcvr, _, _)) =
+ (callee_ty, &call_expr.kind)
+ {
+ // Type that would have accepted this argument if it hadn't been inferred earlier.
+ // FIXME: We leave an inference variable for now, but it'd be nice to get a more
+ // specific type to increase the accuracy of the diagnostic.
+ let expected = self.infcx.next_ty_var(TypeVariableOrigin {
+ kind: TypeVariableOriginKind::MiscVariable,
+ span: full_call_span,
+ });
+ self.point_at_expr_source_of_inferred_type(&mut err, rcvr, expected, callee_ty);
+ }
// Call out where the function is defined
self.label_fn_like(
&mut err,
hir_id: call_hir_id,
span: call_span,
..
- }) = hir.get(hir.get_parent_node(expr.hir_id))
+ }) = hir.get_parent(expr.hir_id)
&& callee.hir_id == expr.hir_id
{
if self.closure_span_overlaps_error(error, *call_span) {
self.typeck_results
.borrow()
.liberated_fn_sigs()
- .get(self.tcx.hir().get_parent_node(self.body_id))
+ .get(self.tcx.hir().parent_id(self.body_id))
.copied()
}
// Check if the parent expression is a call to Pin::new. If it
// is and we were expecting a Box, ergo Pin<Box<expected>>, we
// can suggest Box::pin.
- let parent = self.tcx.hir().get_parent_node(expr.hir_id);
+ let parent = self.tcx.hir().parent_id(expr.hir_id);
let Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) = self.tcx.hir().find(parent) else {
return false;
};
diag_expr_id: HirId,
) {
let hir = self.tcx.hir();
- let parent = match hir.find_parent_node(place_with_id.hir_id) {
+ let parent = match hir.opt_parent_id(place_with_id.hir_id) {
Some(parent) => parent,
None => place_with_id.hir_id,
};
_ => None,
})
.unwrap_or_else(|| match tcx.hir().get(id) {
- Node::AnonConst(_) => match tcx.hir().get(tcx.hir().get_parent_node(id)) {
+ Node::AnonConst(_) => match tcx.hir().get(tcx.hir().parent_id(id)) {
Node::Expr(&hir::Expr {
kind: hir::ExprKind::ConstBlock(ref anon_const),
..
let sugg_span = if let SelfSource::MethodCall(expr) = source {
// Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing.
- self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)).span
+ self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id)).span
} else {
span
};
if let SelfSource::MethodCall(rcvr_expr) = source {
self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| {
let call_expr =
- self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(rcvr_expr.hir_id));
+ self.tcx.hir().expect_expr(self.tcx.hir().parent_id(rcvr_expr.hir_id));
let probe =
self.lookup_probe(item_name, output_ty, call_expr, ProbeScope::AllTraits);
probe.is_ok()
let msg = "remove this method call";
let mut fallback_span = true;
if let SelfSource::MethodCall(expr) = source {
- let call_expr =
- self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
+ let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id));
if let Some(span) = call_expr.span.trim_start(expr.span) {
err.span_suggestion(span, msg, "", Applicability::MachineApplicable);
fallback_span = false;
Applicability::MachineApplicable,
);
} else {
- let call_expr = tcx.hir().expect_expr(tcx.hir().get_parent_node(expr.hir_id));
+ let call_expr = tcx.hir().expect_expr(tcx.hir().parent_id(expr.hir_id));
if let Some(span) = call_expr.span.trim_start(item_name.span) {
err.span_suggestion(
let filename = tcx.sess.source_map().span_to_filename(span);
let parent_node =
- self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id));
+ self.tcx.hir().get_parent(hir_id);
let msg = format!(
"you must specify a type for this binding, like `{}`",
concrete_type,
let mut visitor = LetVisitor { result: None, ident_name: seg1.ident.name };
visitor.visit_body(&body);
- let parent = self.tcx.hir().get_parent_node(seg1.hir_id);
+ let parent = self.tcx.hir().parent_id(seg1.hir_id);
if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent)
&& let Some(expr) = visitor.result
&& let Some(self_ty) = self.node_ty_opt(expr.hir_id)
&& let Some((fields, substs)) =
self.get_field_candidates_considering_privacy(span, actual, mod_id)
{
- let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
+ let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id));
let lang_items = self.tcx.lang_items();
let never_mention_traits = [
) {
let tcx = self.tcx;
let SelfSource::MethodCall(expr) = source else { return; };
- let call_expr = tcx.hir().expect_expr(tcx.hir().get_parent_node(expr.hir_id));
+ let call_expr = tcx.hir().expect_expr(tcx.hir().parent_id(expr.hir_id));
let ty::Adt(kind, substs) = actual.kind() else { return; };
match kind.adt_kind() {
return false;
}
- let parent = self.tcx.hir().get_parent_node(expr.hir_id);
+ let parent = self.tcx.hir().parent_id(expr.hir_id);
if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) &&
let hir::ExprKind::MethodCall(
hir::PathSegment { ident: method_name, .. },
let tcx = self.tcx;
if let PatKind::Ref(inner, mutbl) = pat.kind
&& let PatKind::Binding(_, _, binding, ..) = inner.kind {
- let binding_parent_id = tcx.hir().get_parent_node(pat.hir_id);
+ let binding_parent_id = tcx.hir().parent_id(pat.hir_id);
let binding_parent = tcx.hir().get(binding_parent_id);
debug!(?inner, ?pat, ?binding_parent);
res.descr(),
),
);
- match self.tcx.hir().get(self.tcx.hir().get_parent_node(pat.hir_id)) {
+ match self.tcx.hir().get_parent(pat.hir_id) {
hir::Node::PatField(..) => {
e.span_suggestion_verbose(
ident.span.shrink_to_hi(),
assert!(mask <= 0xFF);
let byte = word & mask;
- result.push_str(&format!("{}{:02x}", sep, byte));
+ result.push_str(&format!("{sep}{byte:02x}"));
if remain <= 8 {
break;
};
debug_assert!(
self.check_invariants(),
- "wrong intervals after insert {:?}..={:?} to {:?}",
- start,
- end,
- self
+ "wrong intervals after insert {start:?}..={end:?} to {self:?}"
);
result
}
span: Span,
) {
let hir = self.tcx.hir();
- let fn_hir_id = hir.get_parent_node(cause.body_id);
+ let fn_hir_id = hir.parent_id(cause.body_id);
if let Some(node) = self.tcx.hir().find(fn_hir_id) &&
let hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(_sig, _, body_id), ..
let hir::StmtKind::Local(local) = &stmt.kind else { continue; };
local.pat.walk(&mut find_compatible_candidates);
}
- match hir.find(hir.get_parent_node(blk.hir_id)) {
- Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => {
- match hir.find(hir.get_parent_node(*hir_id)) {
- Some(hir::Node::Arm(hir::Arm { pat, .. })) => {
- pat.walk(&mut find_compatible_candidates);
- }
- Some(
- hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. })
- | hir::Node::ImplItem(hir::ImplItem {
- kind: hir::ImplItemKind::Fn(_, body),
- ..
- })
- | hir::Node::TraitItem(hir::TraitItem {
- kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)),
- ..
- })
- | hir::Node::Expr(hir::Expr {
- kind: hir::ExprKind::Closure(hir::Closure { body, .. }),
- ..
- }),
- ) => {
- for param in hir.body(*body).params {
- param.pat.walk(&mut find_compatible_candidates);
- }
- }
- Some(hir::Node::Expr(hir::Expr {
- kind:
- hir::ExprKind::If(
- hir::Expr { kind: hir::ExprKind::Let(let_), .. },
- then_block,
- _,
- ),
+ match hir.find_parent(blk.hir_id) {
+ Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => match hir.find_parent(*hir_id) {
+ Some(hir::Node::Arm(hir::Arm { pat, .. })) => {
+ pat.walk(&mut find_compatible_candidates);
+ }
+ Some(
+ hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. })
+ | hir::Node::ImplItem(hir::ImplItem {
+ kind: hir::ImplItemKind::Fn(_, body), ..
+ })
+ | hir::Node::TraitItem(hir::TraitItem {
+ kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)),
+ ..
+ })
+ | hir::Node::Expr(hir::Expr {
+ kind: hir::ExprKind::Closure(hir::Closure { body, .. }),
..
- })) if then_block.hir_id == *hir_id => {
- let_.pat.walk(&mut find_compatible_candidates);
+ }),
+ ) => {
+ for param in hir.body(*body).params {
+ param.pat.walk(&mut find_compatible_candidates);
}
- _ => {}
}
- }
+ Some(hir::Node::Expr(hir::Expr {
+ kind:
+ hir::ExprKind::If(
+ hir::Expr { kind: hir::ExprKind::Let(let_), .. },
+ then_block,
+ _,
+ ),
+ ..
+ })) if then_block.hir_id == *hir_id => {
+ let_.pat.walk(&mut find_compatible_candidates);
+ }
+ _ => {}
+ },
_ => {}
}
.as_local()
.map_or(false, |def_id| self.opaque_type_origin(def_id, span).is_some())
};
- let value = value.fold_with(&mut ty::fold::BottomUpFolder {
+ let value = value.fold_with(&mut BottomUpFolder {
tcx: self.tcx,
lt_op: |lt| lt,
ct_op: |ct| ct,
.into_iter()
.map(|s| {
let sess = ParseSess::with_silent_emitter(Some(format!(
- "this error occurred on the command line: `--cfg={}`",
- s
+ "this error occurred on the command line: `--cfg={s}`"
)));
let filename = FileName::cfg_spec_source_code(&s);
'specs: for s in specs {
let sess = ParseSess::with_silent_emitter(Some(format!(
- "this error occurred on the command line: `--check-cfg={}`",
- s
+ "this error occurred on the command line: `--check-cfg={s}`"
)));
let filename = FileName::cfg_spec_source_code(&s);
// prevents `make` from spitting out an error if a file is later
// deleted. For more info see #28735
for path in files {
- writeln!(file, "{}:", path)?;
+ writeln!(file, "{path}:")?;
}
// Emit special comments with information about accessed environment variables.
envs.sort_unstable();
writeln!(file)?;
for (k, v) in envs {
- write!(file, "# env-dep:{}", k)?;
+ write!(file, "# env-dep:{k}")?;
if let Some(v) = v {
- write!(file, "={}", v)?;
+ write!(file, "={v}")?;
}
writeln!(file)?;
}
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
use rustc_session::config::rustc_optgroups;
+use rustc_session::config::TraitSolver;
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
use rustc_session::config::{
BranchProtection, Externs, OomStrategy, OutputType, OutputTypes, PAuthKey, PacRet,
pac_ret: Some(PacRet { leaf: true, key: PAuthKey::B })
})
);
- tracked!(chalk, true);
tracked!(codegen_backend, Some("abc".to_string()));
tracked!(crate_attr, vec!["abc".to_string()]);
tracked!(debug_info_for_profiling, true);
tracked!(thinlto, Some(true));
tracked!(thir_unsafeck, true);
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
+ tracked!(trait_solver, TraitSolver::Chalk);
tracked!(translate_remapped_path_to_local_path, false);
tracked!(trap_unreachable, Some(false));
tracked!(treat_err_as_bug, NonZeroUsize::new(1));
fn load_backend_from_dylib(path: &Path) -> MakeBackendFn {
let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| {
- let err = format!("couldn't load codegen backend {:?}: {}", path, err);
+ let err = format!("couldn't load codegen backend {path:?}: {err}");
early_error(ErrorOutputType::default(), &err);
});
let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") }
.unwrap_or_else(|e| {
- let err = format!("couldn't load codegen backend: {}", e);
+ let err = format!("couldn't load codegen backend: {e}");
early_error(ErrorOutputType::default(), &err);
});
.join("\n* ");
let err = format!(
"failed to find a `codegen-backends` folder \
- in the sysroot candidates:\n* {}",
- candidates
+ in the sysroot candidates:\n* {candidates}"
);
early_error(ErrorOutputType::default(), &err);
});
let expected_names = &[
format!("rustc_codegen_{}-{}", backend_name, env!("CFG_RELEASE")),
- format!("rustc_codegen_{}", backend_name),
+ format!("rustc_codegen_{backend_name}"),
];
for entry in d.filter_map(|e| e.ok()) {
let path = entry.path();
match file {
Some(ref s) => load_backend_from_dylib(s),
None => {
- let err = format!("unsupported builtin codegen backend `{}`", backend_name);
+ let err = format!("unsupported builtin codegen backend `{backend_name}`");
early_error(ErrorOutputType::default(), &err);
}
}
BuiltinLintDiagnostics::UnknownCrateTypes(
span,
"did you mean".to_string(),
- format!("\"{}\"", candidate),
+ format!("\"{candidate}\""),
),
);
} else {
fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
let map = cx.tcx.hir();
- if matches!(map.get(map.get_parent_node(field.hir_id)), Node::Variant(_)) {
+ if matches!(map.get_parent(field.hir_id), Node::Variant(_)) {
return;
}
self.perform_lint(cx, "field", field.def_id, field.vis_span, false);
TyKind::Path(QPath::Resolved(_, path)) => {
if lint_ty_kind_usage(cx, &path.res) {
let hir = cx.tcx.hir();
- let span = match hir.find(hir.get_parent_node(ty.hir_id)) {
+ let span = match hir.find_parent(ty.hir_id) {
Some(Node::Pat(Pat {
kind:
PatKind::Path(qpath)
fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
if let PatKind::Binding(_, hid, ident, _) = p.kind {
- if let hir::Node::PatField(field) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
- {
+ if let hir::Node::PatField(field) = cx.tcx.hir().get_parent(hid) {
if !field.is_shorthand {
// Only check if a new name has been introduced, to avoid warning
// on both the struct definition and this pattern.
) -> bool {
// We only want to handle exclusive (`..`) ranges,
// which are represented as `ExprKind::Struct`.
- let par_id = cx.tcx.hir().get_parent_node(expr.hir_id);
+ let par_id = cx.tcx.hir().parent_id(expr.hir_id);
let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false };
- let field_par_id = cx.tcx.hir().get_parent_node(field.hir_id);
- let Node::Expr(struct_expr) = cx.tcx.hir().get(field_par_id) else { return false };
+ let Node::Expr(struct_expr) = cx.tcx.hir().get_parent(field.hir_id) else { return false };
if !is_range_literal(struct_expr) {
return false;
};
_ => bug!(),
};
if lit_val < min || lit_val > max {
- let parent_id = cx.tcx.hir().get_parent_node(e.hir_id);
+ let parent_id = cx.tcx.hir().parent_id(e.hir_id);
if let Node::Expr(par_e) = cx.tcx.hir().get(parent_id) {
match par_e.kind {
hir::ExprKind::Cast(..) => {
/// Supposed to be used for all variables except those set for build scripts by cargo
/// <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts>
fn tracked_env_var_os<K: AsRef<OsStr> + Display>(key: K) -> Option<OsString> {
- println!("cargo:rerun-if-env-changed={}", key);
+ println!("cargo:rerun-if-env-changed={key}");
env::var_os(key)
}
let output = match cmd.stderr(Stdio::inherit()).output() {
Ok(status) => status,
Err(e) => {
- println!("\n\nfailed to execute command: {:?}\nerror: {}\n\n", cmd, e);
+ println!("\n\nfailed to execute command: {cmd:?}\nerror: {e}\n\n");
std::process::exit(1);
}
};
fn main() {
for component in REQUIRED_COMPONENTS.iter().chain(OPTIONAL_COMPONENTS.iter()) {
- println!("cargo:rustc-check-cfg=values(llvm_component,\"{}\")", component);
+ println!("cargo:rustc-check-cfg=values(llvm_component,\"{component}\")");
}
if tracked_env_var_os("RUST_CHECK").is_some() {
for component in REQUIRED_COMPONENTS {
if !components.contains(component) {
- panic!("require llvm component {} but wasn't found", component);
+ panic!("require llvm component {component} but wasn't found");
}
}
for component in components.iter() {
- println!("cargo:rustc-cfg=llvm_component=\"{}\"", component);
+ println!("cargo:rustc-cfg=llvm_component=\"{component}\"");
}
// Link in our own LLVM shims, compiled with the same flags as LLVM
}
let kind = if name.starts_with("LLVM") { llvm_kind } else { "dylib" };
- println!("cargo:rustc-link-lib={}={}", kind, name);
+ println!("cargo:rustc-link-lib={kind}={name}");
}
// LLVM ldflags
println!("cargo:rustc-link-search=native={}", stripped.replace(&host, &target));
}
} else if let Some(stripped) = lib.strip_prefix("-LIBPATH:") {
- println!("cargo:rustc-link-search=native={}", stripped);
+ println!("cargo:rustc-link-search=native={stripped}");
} else if let Some(stripped) = lib.strip_prefix("-l") {
- println!("cargo:rustc-link-lib={}", stripped);
+ println!("cargo:rustc-link-lib={stripped}");
} else if let Some(stripped) = lib.strip_prefix("-L") {
- println!("cargo:rustc-link-search=native={}", stripped);
+ println!("cargo:rustc-link-search=native={stripped}");
}
}
if let Some(s) = llvm_linker_flags {
for lib in s.into_string().unwrap().split_whitespace() {
if let Some(stripped) = lib.strip_prefix("-l") {
- println!("cargo:rustc-link-lib={}", stripped);
+ println!("cargo:rustc-link-lib={stripped}");
} else if let Some(stripped) = lib.strip_prefix("-L") {
- println!("cargo:rustc-link-search=native={}", stripped);
+ println!("cargo:rustc-link-search=native={stripped}");
}
}
}
let path = PathBuf::from(s);
println!("cargo:rustc-link-search=native={}", path.parent().unwrap().display());
if target.contains("windows") {
- println!("cargo:rustc-link-lib=static:-bundle={}", stdcppname);
+ println!("cargo:rustc-link-lib=static:-bundle={stdcppname}");
} else {
- println!("cargo:rustc-link-lib=static={}", stdcppname);
+ println!("cargo:rustc-link-lib=static={stdcppname}");
}
} else if cxxflags.contains("stdlib=libc++") {
println!("cargo:rustc-link-lib=c++");
} else {
- println!("cargo:rustc-link-lib={}", stdcppname);
+ println!("cargo:rustc-link-lib={stdcppname}");
}
}
match self {
Error::InvalidColorValue(value) => write!(
formatter,
- "invalid log color value '{}': expected one of always, never, or auto",
- value,
+ "invalid log color value '{value}': expected one of always, never, or auto",
),
Error::NonUnicodeColorValue => write!(
formatter,
let span = attr.span().unwrap();
let path = path_to_string(&attr.path);
match meta {
- Meta::Path(_) => span_err(span, &format!("`#[{}]` is not a valid attribute", path)),
+ Meta::Path(_) => span_err(span, &format!("`#[{path}]` is not a valid attribute")),
Meta::NameValue(_) => {
- span_err(span, &format!("`#[{} = ...]` is not a valid attribute", path))
+ span_err(span, &format!("`#[{path} = ...]` is not a valid attribute"))
}
- Meta::List(_) => span_err(span, &format!("`#[{}(...)]` is not a valid attribute", path)),
+ Meta::List(_) => span_err(span, &format!("`#[{path}(...)]` is not a valid attribute")),
}
}
let meta = match nested {
syn::NestedMeta::Meta(meta) => meta,
syn::NestedMeta::Lit(_) => {
- return span_err(span, &format!("`#[{}(\"...\")]` is not a valid attribute", name));
+ return span_err(span, &format!("`#[{name}(\"...\")]` is not a valid attribute"));
}
};
let path = path_to_string(meta.path());
match meta {
Meta::NameValue(..) => {
- span_err(span, &format!("`#[{}({} = ...)]` is not a valid attribute", name, path))
- }
- Meta::Path(..) => {
- span_err(span, &format!("`#[{}({})]` is not a valid attribute", name, path))
+ span_err(span, &format!("`#[{name}({path} = ...)]` is not a valid attribute"))
}
+ Meta::Path(..) => span_err(span, &format!("`#[{name}({path})]` is not a valid attribute")),
Meta::List(..) => {
- span_err(span, &format!("`#[{}({}(...))]` is not a valid attribute", name, path))
+ span_err(span, &format!("`#[{name}({path}(...))]` is not a valid attribute"))
}
}
}
opt: Default::default(),
};
let dl = DisplayList::from(snippet);
- eprintln!("{}\n", dl);
+ eprintln!("{dl}\n");
}
continue;
}
Diagnostic::spanned(
path_span,
Level::Error,
- format!("overrides existing {}: `{}`", kind, id),
+ format!("overrides existing {kind}: `{id}`"),
)
.span_help(previous_defns[&id], "previously defined in this resource")
.emit();
throw_span_err!(
attr.span().unwrap(),
&format!(
- "diagnostic slug must be first argument of a `#[{}(...)]` attribute",
- name
+ "diagnostic slug must be first argument of a `#[{name}(...)]` attribute"
)
);
};
None => {
span_err(
span.unwrap(),
- &format!("`{}` doesn't refer to a field on this type", field),
+ &format!("`{field}` doesn't refer to a field on this type"),
)
.emit();
quote! {
if suggestion_kind != SuggestionKind::Normal {
invalid_attr(attr, &meta)
.help(format!(
- r#"Use `#[suggestion(..., style = "{}")]` instead"#,
- suggestion_kind
+ r#"Use `#[suggestion(..., style = "{suggestion_kind}")]` instead"#
))
.emit();
}
if suggestion_kind != SuggestionKind::Normal {
invalid_attr(attr, &meta)
.help(format!(
- r#"Use `#[multipart_suggestion(..., style = "{}")]` instead"#,
- suggestion_kind
+ r#"Use `#[multipart_suggestion(..., style = "{suggestion_kind}")]` instead"#
))
.emit();
}
};
if let Some(old) = max.replace(literal.lit) {
- panic!("Specified multiple max: {:?}", old);
+ panic!("Specified multiple max: {old:?}");
}
false
};
if let Some(old) = debug_format.replace(literal.lit) {
- panic!("Specified multiple debug format options: {:?}", old);
+ panic!("Specified multiple debug format options: {old:?}");
}
false
.unwrap();
},
);
- let doc_string = format!("[query description - consider adding a doc-comment!] {}", doc_string);
+ let doc_string = format!("[query description - consider adding a doc-comment!] {doc_string}");
Ok(parse_quote! { #[doc = #doc_string] })
}
let mut check_dup = |span: Span, str: &str, errors: &mut Errors| {
if let Some(prev_span) = keys.get(str) {
- errors.error(span, format!("Symbol `{}` is duplicated", str));
+ errors.error(span, format!("Symbol `{str}` is duplicated"));
errors.error(*prev_span, "location of previous definition".to_string());
} else {
keys.insert(str.to_string(), span);
let mut check_order = |span: Span, str: &str, errors: &mut Errors| {
if let Some((prev_span, ref prev_str)) = prev_key {
if str < prev_str {
- errors.error(span, format!("Symbol `{}` must precede `{}`", str, prev_str));
- errors.error(prev_span, format!("location of previous symbol `{}`", prev_str));
+ errors.error(span, format!("Symbol `{str}` must precede `{prev_str}`"));
+ errors.error(prev_span, format!("location of previous symbol `{prev_str}`"));
}
}
prev_key = Some((span, str.to_string()));
writeln!(fmt, "resolved crates:")?;
for (cnum, data) in self.0.iter_crate_data() {
writeln!(fmt, " name: {}", data.name())?;
- writeln!(fmt, " cnum: {}", cnum)?;
+ writeln!(fmt, " cnum: {cnum}")?;
writeln!(fmt, " hash: {}", data.hash())?;
writeln!(fmt, " reqd: {:?}", data.dep_kind())?;
let CrateSource { dylib, rlib, rmeta } = data.source();
pub(crate) fn get_crate_data(&self, cnum: CrateNum) -> CrateMetadataRef<'_> {
let cdata = self.metas[cnum]
.as_ref()
- .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum));
+ .unwrap_or_else(|| panic!("Failed to get crate data for {cnum:?}"));
CrateMetadataRef { cdata, cstore: self }
}
for path in search_paths {
for (prefix, suffix) in &formats {
- let test = path.join(format!("{}{}{}", prefix, name, suffix));
+ let test = path.join(format!("{prefix}{name}{suffix}"));
if test.exists() {
return test;
}
.root
.syntax_contexts
.get(cdata, id)
- .unwrap_or_else(|| panic!("Missing SyntaxContext {:?} for crate {:?}", id, cname))
+ .unwrap_or_else(|| panic!("Missing SyntaxContext {id:?} for crate {cname:?}"))
.decode((cdata, sess))
})
}
.tables
.def_span
.get(self, index)
- .unwrap_or_else(|| panic!("Missing span for {:?}", index))
+ .unwrap_or_else(|| panic!("Missing span for {index:?}"))
.decode((self, sess))
}
.tables
.proc_macro_quoted_spans
.get(self, index)
- .unwrap_or_else(|| panic!("Missing proc macro quoted span: {:?}", index))
+ .unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}"))
.decode((self, sess))
}
.trait_impl_trait_tys
.get(cdata, def_id.index)
.map(|lazy| lazy.decode((cdata, tcx)))
- .process_decoded(tcx, || panic!("{:?} does not have trait_impl_trait_tys", def_id)))
+ .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys")))
}
visibility => { cdata.get_visibility(def_id.index) }
let _ = d.read_raw_bytes(len);
let inner = odht::HashTable::from_raw_bytes(o).unwrap_or_else(|e| {
- panic!("decode error: {}", e);
+ panic!("decode error: {e}");
});
DefPathHashMapRef::OwnedFromMetadata(inner)
}
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for CrateNum {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) {
if *self != LOCAL_CRATE && s.is_proc_macro {
- panic!("Attempted to encode non-local CrateNum {:?} for proc-macro crate", self);
+ panic!("Attempted to encode non-local CrateNum {self:?} for proc-macro crate");
}
s.emit_u32(self.as_u32());
}
// Introduce a new scope so that we drop the 'lock()' temporary
match &*source_file.external_src.lock() {
ExternalSource::Foreign { metadata_index, .. } => *metadata_index,
- src => panic!("Unexpected external source {:?}", src),
+ src => panic!("Unexpected external source {src:?}"),
}
};
let prefix = "meta-stats";
let perc = |bytes| (bytes * 100) as f64 / total_bytes as f64;
- eprintln!("{} METADATA STATS", prefix);
+ eprintln!("{prefix} METADATA STATS");
eprintln!("{} {:<23}{:>10}", prefix, "Section", "Size");
- eprintln!(
- "{} ----------------------------------------------------------------",
- prefix
- );
+ eprintln!("{prefix} ----------------------------------------------------------------");
for (label, size) in stats {
eprintln!(
"{} {:<23}{:>10} ({:4.1}%)",
perc(size)
);
}
- eprintln!(
- "{} ----------------------------------------------------------------",
- prefix
- );
+ eprintln!("{prefix} ----------------------------------------------------------------");
eprintln!(
"{} {:<23}{:>10} (of which {:.1}% are zero bytes)",
prefix,
to_readable_str(total_bytes),
perc(zero_bytes)
);
- eprintln!("{}", prefix);
+ eprintln!("{prefix}");
}
root
}
loop {
// There are nodes that do not have entries, so we need to skip them.
- let parent_id = self.map.get_parent_node(self.current_id);
+ let parent_id = self.map.parent_id(self.current_id);
if parent_id == self.current_id {
self.current_id = CRATE_HIR_ID;
},
Node::Variant(_) => DefKind::Variant,
Node::Ctor(variant_data) => {
- let ctor_of = match self.find(self.get_parent_node(hir_id)) {
+ let ctor_of = match self.find_parent(hir_id) {
Some(Node::Item(..)) => def::CtorOf::Struct,
Some(Node::Variant(..)) => def::CtorOf::Variant,
_ => unreachable!(),
}
}
Node::AnonConst(_) => {
- let inline = match self.find(self.get_parent_node(hir_id)) {
+ let inline = match self.find_parent(hir_id) {
Some(Node::Expr(&Expr {
kind: ExprKind::ConstBlock(ref anon_const), ..
})) if anon_const.hir_id == hir_id => true,
/// Finds the id of the parent node to this one.
///
/// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
- pub fn find_parent_node(self, id: HirId) -> Option<HirId> {
+ pub fn opt_parent_id(self, id: HirId) -> Option<HirId> {
if id.local_id == ItemLocalId::from_u32(0) {
Some(self.tcx.hir_owner_parent(id.owner))
} else {
}
#[track_caller]
- pub fn get_parent_node(self, hir_id: HirId) -> HirId {
- self.find_parent_node(hir_id)
+ pub fn parent_id(self, hir_id: HirId) -> HirId {
+ self.opt_parent_id(hir_id)
.unwrap_or_else(|| bug!("No parent for node {:?}", self.node_to_string(hir_id)))
}
+ pub fn get_parent(self, hir_id: HirId) -> Node<'hir> {
+ self.get(self.parent_id(hir_id))
+ }
+
+ pub fn find_parent(self, hir_id: HirId) -> Option<Node<'hir>> {
+ self.find(self.opt_parent_id(hir_id)?)
+ }
+
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
pub fn find(self, id: HirId) -> Option<Node<'hir>> {
if id.local_id == ItemLocalId::from_u32(0) {
/// which this is the body of, i.e., a `fn`, `const` or `static`
/// item (possibly associated), a closure, or a `hir::AnonConst`.
pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId {
- let parent = self.get_parent_node(hir_id);
+ let parent = self.parent_id(hir_id);
assert!(self.find(parent).map_or(false, |n| is_body_owner(n, hir_id)), "{hir_id:?}");
parent
}
}
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
- /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
+ /// until the crate root is reached. Prefer this over your own loop using `parent_id`.
#[inline]
pub fn parent_id_iter(self, current_id: HirId) -> impl Iterator<Item = HirId> + 'hir {
ParentHirIterator { current_id, map: self }
}
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
- /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
+ /// until the crate root is reached. Prefer this over your own loop using `parent_id`.
#[inline]
pub fn parent_iter(self, current_id: HirId) -> impl Iterator<Item = (HirId, Node<'hir>)> {
self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.find(id)?)))
}
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
- /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
+ /// until the crate root is reached. Prefer this over your own loop using `parent_id`.
#[inline]
pub fn parent_owner_iter(self, current_id: HirId) -> ParentOwnerIterator<'hir> {
ParentOwnerIterator { current_id, map: self }
/// Checks if the node is left-hand side of an assignment.
pub fn is_lhs(self, id: HirId) -> bool {
- match self.find(self.get_parent_node(id)) {
+ match self.find_parent(id) {
Some(Node::Expr(expr)) => match expr.kind {
ExprKind::Assign(lhs, _rhs, _span) => lhs.hir_id == id,
_ => false,
Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident),
// A `Ctor` doesn't have an identifier itself, but its parent
// struct/variant does. Compare with `hir::Map::opt_span`.
- Node::Ctor(..) => match self.find(self.get_parent_node(id))? {
+ Node::Ctor(..) => match self.find_parent(id)? {
Node::Item(item) => Some(item.ident),
Node::Variant(variant) => Some(variant.ident),
_ => unreachable!(),
ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()),
_ => named_span(item.span, item.ident, None),
},
- Node::Ctor(_) => return self.opt_span(self.get_parent_node(hir_id)),
+ Node::Ctor(_) => return self.opt_span(self.parent_id(hir_id)),
Node::Expr(Expr {
kind: ExprKind::Closure(Closure { fn_decl_span, .. }),
span,
Node::PatField(field) => field.span,
Node::Arm(arm) => arm.span,
Node::Block(block) => block.span,
- Node::Ctor(..) => self.span_with_body(self.get_parent_node(hir_id)),
+ Node::Ctor(..) => self.span_with_body(self.parent_id(hir_id)),
Node::Lifetime(lifetime) => lifetime.ident.span,
Node::GenericParam(param) => param.span,
Node::Infer(i) => i.span,
/// Returns the HirId of `N` in `struct Foo<const N: usize = { ... }>` when
/// called with the HirId for the `{ ... }` anon const
pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option<LocalDefId> {
- match self.get(self.get_parent_node(anon_const)) {
+ match self.get_parent(anon_const) {
Node::GenericParam(GenericParam {
def_id: param_id,
kind: GenericParamKind::Const { .. },
if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) {
return id;
}
- let next = hir.get_parent_node(id);
+ let next = hir.parent_id(id);
if next == id {
bug!("lint traversal reached the root of the crate");
}
}
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
- let parent_substs = if let Some(parent_hir_id) = tcx.hir().find_parent_node(hir_id) {
+ let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id) {
if let Some(parent_did) = tcx.hir().opt_local_def_id(parent_hir_id) {
InternalSubsts::identity_for_item(tcx, parent_did.to_def_id())
} else {
.def_id
.as_local()
.map(|id| hir.local_def_id_to_hir_id(id))
- .and_then(|id| self.hir().find(self.hir().get_parent_node(id)))
+ .and_then(|id| self.hir().find_parent(id))
.as_ref()
.and_then(|node| node.generics())
{
fn check_let_chain(&mut self, cx: &mut MatchCheckCtxt<'p, 'tcx>, pat_id: HirId) -> bool {
let hir = self.tcx.hir();
- let parent = hir.get_parent_node(pat_id);
+ let parent = hir.parent_id(pat_id);
// First, figure out if the given pattern is part of a let chain,
// and if so, obtain the top node of the chain.
let mut top = parent;
let mut part_of_chain = false;
loop {
- let new_top = hir.get_parent_node(top);
+ let new_top = hir.parent_id(top);
if let hir::Node::Expr(
hir::Expr {
kind: hir::ExprKind::Binary(Spanned { node: hir::BinOpKind::And, .. }, lhs, rhs),
fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource {
let hir = tcx.hir();
- let parent = hir.get_parent_node(pat_id);
+ let parent = hir.parent_id(pat_id);
let_source_parent(tcx, parent, Some(pat_id))
}
_ => {}
}
- let parent_parent = hir.get_parent_node(parent);
+ let parent_parent = hir.parent_id(parent);
let parent_parent_node = hir.get(parent_parent);
match parent_parent_node {
hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), .. }) => {
_ => {}
}
- let parent_parent_parent = hir.get_parent_node(parent_parent);
- let parent_parent_parent_parent = hir.get_parent_node(parent_parent_parent);
+ let parent_parent_parent = hir.parent_id(parent_parent);
+ let parent_parent_parent_parent = hir.parent_id(parent_parent_parent);
let parent_parent_parent_parent_node = hir.get(parent_parent_parent_parent);
if let hir::Node::Expr(hir::Expr {
| mir::TerminatorKind::InlineAsm { cleanup: Some(unwind), .. }
if unwind == bb =>
{
- if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
+ if dead_unwinds.map_or(true, |dead| !dead.contains(pred)) {
propagate(pred, exit_state);
}
}
", "
};
- write!(f, "{}", delim)?;
+ write!(f, "{delim}")?;
idx.fmt_with(ctxt, f)?;
first = false;
}
", "
};
- write!(f, "{}", delim)?;
+ write!(f, "{delim}")?;
idx.fmt_with(ctxt, f)?;
first = false;
}
fn graph_id(&self) -> dot::Id<'_> {
let name = graphviz_safe_def_name(self.body.source.def_id());
- dot::Id::new(format!("graph_for_def_id_{}", name)).unwrap()
+ dot::Id::new(format!("graph_for_def_id_{name}")).unwrap()
}
fn node_id(&self, n: &Self::Node) -> dot::Id<'_> {
" cellpadding=\"3\"",
" sides=\"rb\"",
);
- write!(w, r#"<table{fmt}>"#, fmt = table_fmt)?;
+ write!(w, r#"<table{table_fmt}>"#)?;
// A + B: Block header
match self.style {
write!(w, concat!("<tr>", r#"<td colspan="2" {fmt}>MIR</td>"#,), fmt = fmt,)?;
for name in state_column_names {
- write!(w, "<td {fmt}>{name}</td>", fmt = fmt, name = name)?;
+ write!(w, "<td {fmt}>{name}</td>")?;
}
write!(w, "</tr>")
};
for (i, statement) in body[block].statements.iter().enumerate() {
- let statement_str = format!("{:?}", statement);
- let index_str = format!("{}", i);
+ let statement_str = format!("{statement:?}");
+ let index_str = format!("{i}");
let after = next_in_dataflow_order(&mut afters);
let before = befores.as_mut().map(next_in_dataflow_order);
self.write_row(w, &index_str, &statement_str, |_this, w, fmt| {
if let Some(before) = before {
- write!(w, r#"<td {fmt} align="left">{diff}</td>"#, fmt = fmt, diff = before)?;
+ write!(w, r#"<td {fmt} align="left">{before}</td>"#)?;
}
- write!(w, r#"<td {fmt} align="left">{diff}</td>"#, fmt = fmt, diff = after)
+ write!(w, r#"<td {fmt} align="left">{after}</td>"#)
})?;
}
self.write_row(w, "T", &terminator_str, |_this, w, fmt| {
if let Some(before) = before {
- write!(w, r#"<td {fmt} align="left">{diff}</td>"#, fmt = fmt, diff = before)?;
+ write!(w, r#"<td {fmt} align="left">{before}</td>"#)?;
}
- write!(w, r#"<td {fmt} align="left">{diff}</td>"#, fmt = fmt, diff = after)
+ write!(w, r#"<td {fmt} align="left">{after}</td>"#)
})
}
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(w, "MovePath {{")?;
if let Some(parent) = self.parent {
- write!(w, " parent: {:?},", parent)?;
+ write!(w, " parent: {parent:?},")?;
}
if let Some(first_child) = self.first_child {
- write!(w, " first_child: {:?},", first_child)?;
+ write!(w, " first_child: {first_child:?},")?;
}
if let Some(next_sibling) = self.next_sibling {
- write!(w, " next_sibling: {:?}", next_sibling)?;
+ write!(w, " next_sibling: {next_sibling:?}")?;
}
write!(w, " place: {:?} }}", self.place)
}
) -> std::fmt::Result {
for (local, place) in map.locals.iter_enumerated() {
if let Some(place) = place {
- debug_with_context_rec(*place, &format!("{:?}", local), new, old, map, f)?;
+ debug_with_context_rec(*place, &format!("{local:?}"), new, old, map, f)?;
}
}
Ok(())
/// Returns the sequence of passes that do the initial cleanup of runtime MIR.
fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
- let passes: &[&dyn MirPass<'tcx>] = &[
- &elaborate_box_derefs::ElaborateBoxDerefs,
- &lower_intrinsics::LowerIntrinsics,
- &simplify::SimplifyCfg::new("elaborate-drops"),
- ];
+ let passes: &[&dyn MirPass<'tcx>] =
+ &[&lower_intrinsics::LowerIntrinsics, &simplify::SimplifyCfg::new("elaborate-drops")];
pm::run_passes(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::PostCleanup)));
}
let formatted_item = with_no_trimmed_paths!(starting_point.node.to_string());
tcx.sess.span_note_without_error(
starting_point.span,
- &format!("the above error was encountered while instantiating `{}`", formatted_item),
+ &format!("the above error was encountered while instantiating `{formatted_item}`"),
);
}
inlining_map.lock_mut().record_accesses(starting_point.node, &neighbors.items);
// FIXME: I can figure out how to do a label with a fluent string with a fixed message,
// or a label with a dynamic value in a hard-coded string, but I haven't figured out
// how to combine the two. 😢
- diag.span_label(span, format!("generic parameter `{}` is unused", name));
+ diag.span_label(span, format!("generic parameter `{name}` is unused"));
}
diag
}
use std::fmt::Write;
let s = &mut String::new();
- let _ = writeln!(s, "{}", label);
+ let _ = writeln!(s, "{label}");
for cgu in cgus {
let _ =
writeln!(s, "CodegenUnit {} estimated size {} :", cgu.name(), cgu.size_estimate());
} else {
if mode_string != "lazy" {
let message = format!(
- "Unknown codegen-item collection mode '{}'. \
- Falling back to 'lazy' mode.",
- mode_string
+ "Unknown codegen-item collection mode '{mode_string}'. \
+ Falling back to 'lazy' mode."
);
tcx.sess.warn(&message);
}
item_keys.sort();
for item in item_keys {
- println!("MONO_ITEM {}", item);
+ println!("MONO_ITEM {item}");
}
}
let (_, all) = tcx.collect_and_partition_mono_items(());
all.iter()
.find(|cgu| cgu.name() == name)
- .unwrap_or_else(|| panic!("failed to find cgu with name {:?}", name))
+ .unwrap_or_else(|| panic!("failed to find cgu with name {name:?}"))
};
}
let new_size = tcx
.layout_of(param_env.and(after_feature_tys))
.map(|l| format!("{:?}", l.size.bytes()))
- .unwrap_or_else(|e| format!("Failed {:?}", e));
+ .unwrap_or_else(|e| format!("Failed {e:?}"));
let old_size = tcx
.layout_of(param_env.and(before_feature_tys))
.map(|l| format!("{:?}", l.size.bytes()))
- .unwrap_or_else(|e| format!("Failed {:?}", e));
+ .unwrap_or_else(|e| format!("Failed {e:?}"));
let closure_span = tcx.def_span(closure_def_id);
let src_file = tcx.sess.source_map().span_to_filename(closure_span);
.source_map()
.span_to_lines(closure_span)
.map(|l| format!("{:?} {:?}", l.lines.first(), l.lines.last()))
- .unwrap_or_else(|e| format!("{:?}", e));
+ .unwrap_or_else(|e| format!("{e:?}"));
if let Err(e) = writeln!(
file,
src_file.prefer_local(),
line_nos
) {
- eprintln!("Error writing to file {}", e)
+ eprintln!("Error writing to file {e}")
}
}
}
Some(pos)
} else {
let pos = self.to_span_index(pos);
- let description = format!("expected `'}}'`, found `{:?}`", maybe);
+ let description = format!("expected `'}}'`, found `{maybe:?}`");
let label = "expected `}`".to_owned();
let (note, secondary_label) = if c == '}' {
(
None
}
} else {
- let description = format!("expected `{:?}` but string was terminated", c);
+ let description = format!("expected `{c:?}` but string was terminated");
// point at closing `"`
let pos = self.input.len() - if self.append_newline { 1 } else { 0 };
let pos = self.to_span_index(pos);
if c == '}' {
- let label = format!("expected `{:?}`", c);
+ let label = format!("expected `{c:?}`");
let (note, secondary_label) = if c == '}' {
(
Some(
should_be_replaced_with_positional_argument: false,
});
} else {
- self.err(description, format!("expected `{:?}`", c), pos.to(pos));
+ self.err(description, format!("expected `{c:?}`"), pos.to(pos));
}
None
}
if level != Level::Direct {
error_msg.push_str(", ");
}
- error_msg.push_str(&format!("{:?}: {}", level, vis_str));
+ error_msg.push_str(&format!("{level:?}: {vis_str}"));
}
} else {
error_msg.push_str("not in the table");
if !old_error_set_ancestry.insert(id) {
break;
}
- let parent = tcx.hir().get_parent_node(id);
+ let parent = tcx.hir().parent_id(id);
if parent == id {
break;
}
// which means that the definition with this hash is guaranteed to
// still exist in the current compilation session.
d.tcx.def_path_hash_to_def_id(def_path_hash, &mut || {
- panic!("Failed to convert DefPathHash {:?}", def_path_hash)
+ panic!("Failed to convert DefPathHash {def_path_hash:?}")
})
}
}
ty::print::with_forced_impl_filename_line!(do_describe(tcx.tcx, key))
);
let description =
- if tcx.sess.verbose() { format!("{} [{:?}]", description, name) } else { description };
+ if tcx.sess.verbose() { format!("{description} [{name:?}]") } else { description };
let span = if kind == dep_graph::DepKind::def_span {
// The `def_span` query is used to calculate `default_span`,
// so exit to avoid infinite recursion.
&self,
builder: &mut QueryKeyStringBuilder<'_, '_>,
) -> StringId {
- let s = format!("{:?}", self);
+ let s = format!("{self:?}");
builder.profiler.alloc_string(&s[..])
}
}
/// Tests whether `node` meets the filter, returning true if so.
pub fn test<K: DepKind>(&self, node: &DepNode<K>) -> bool {
- let debug_str = format!("{:?}", node);
+ let debug_str = format!("{node:?}");
self.text.split('&').map(|s| s.trim()).all(|f| debug_str.contains(f))
}
}
pub fn new(test: &str) -> Result<EdgeFilter<K>, Box<dyn Error>> {
let parts: Vec<_> = test.split("->").collect();
if parts.len() != 2 {
- Err(format!("expected a filter like `a&b -> c&d`, not `{}`", test).into())
+ Err(format!("expected a filter like `a&b -> c&d`, not `{test}`").into())
} else {
Ok(EdgeFilter {
source: DepNodeFilter::new(parts[0]),
}
fn to_debug_str(&self, _: Tcx) -> String {
- format!("{:?}", self)
+ format!("{self:?}")
}
/// This method tries to recover the query key from the given `DepNode`,
assert!(
!self.dep_node_exists(&key),
"forcing query with already existing `DepNode`\n\
- - query-key: {:?}\n\
- - dep-node: {:?}",
- arg,
- key
+ - query-key: {arg:?}\n\
+ - dep-node: {key:?}"
);
let task_deps = if cx.dep_context().is_eval_always(key.kind) {
debug_assert!(
data.colors.get(prev_index).is_none(),
"DepGraph::with_task() - Duplicate DepNodeColor \
- insertion for {:?}",
- key
+ insertion for {key:?}"
);
data.colors.insert(prev_index, color);
TaskDepsRef::Allow(deps) => deps.lock(),
TaskDepsRef::Ignore => return,
TaskDepsRef::Forbid => {
- panic!("Illegal read of: {:?}", dep_node_index)
+ panic!("Illegal read of: {dep_node_index:?}")
}
};
let task_deps = &mut *task_deps;
debug_assert!(
data.colors.get(prev_dep_node_index).is_none(),
"DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \
- insertion for {:?}",
- dep_node
+ insertion for {dep_node:?}"
);
if !side_effects.is_empty() {
if let Some(fingerprint) = fingerprint {
if fingerprint == prev_graph.fingerprint_by_index(prev_index) {
if print_status {
- eprintln!("[task::green] {:?}", key);
+ eprintln!("[task::green] {key:?}");
}
// This is a green node: it existed in the previous compilation,
(dep_node_index, Some((prev_index, DepNodeColor::Green(dep_node_index))))
} else {
if print_status {
- eprintln!("[task::red] {:?}", key);
+ eprintln!("[task::red] {key:?}");
}
// This is a red node: it existed in the previous compilation, its query
}
} else {
if print_status {
- eprintln!("[task::unknown] {:?}", key);
+ eprintln!("[task::unknown] {key:?}");
}
// This is a red node, effectively: it existed in the previous compilation
}
} else {
if print_status {
- eprintln!("[task::new] {:?}", key);
+ eprintln!("[task::new] {key:?}");
}
let fingerprint = fingerprint.unwrap_or(Fingerprint::ZERO);
eprintln!("[incremental]");
eprintln!("[incremental] DepGraph Statistics");
- eprintln!("{}", SEPARATOR);
+ eprintln!("{SEPARATOR}");
eprintln!("[incremental]");
eprintln!("[incremental] Total Node Count: {}", status.total_node_count);
eprintln!("[incremental] Total Edge Count: {}", status.total_edge_count);
if cfg!(debug_assertions) {
- eprintln!("[incremental] Total Edge Reads: {}", total_read_count);
- eprintln!(
- "[incremental] Total Duplicate Edge Reads: {}",
- total_duplicate_read_count
- );
+ eprintln!("[incremental] Total Edge Reads: {total_read_count}");
+ eprintln!("[incremental] Total Duplicate Edge Reads: {total_duplicate_read_count}");
}
eprintln!("[incremental]");
"[incremental] {:<36}| {:<17}| {:<12}| {:<17}|",
"Node Kind", "Node Frequency", "Node Count", "Avg. Edge Count"
);
- eprintln!("{}", SEPARATOR);
+ eprintln!("{SEPARATOR}");
for stat in stats {
let node_kind_ratio =
);
}
- eprintln!("{}", SEPARATOR);
+ eprintln!("{SEPARATOR}");
eprintln!("[incremental]");
}
}
// can be forced from `DepNode`.
debug_assert!(
!qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(),
- "missing on-disk cache entry for {:?}",
- dep_node
+ "missing on-disk cache entry for {dep_node:?}"
);
}
{
assert!(
tcx.dep_graph().is_green(dep_node),
- "fingerprint for green query instance not loaded from cache: {:?}",
- dep_node,
+ "fingerprint for green query instance not loaded from cache: {dep_node:?}",
);
let new_hash = hash_result.map_or(Fingerprint::ZERO, |f| {
sess.emit_err(crate::error::Reentrant);
} else {
let run_cmd = if let Some(crate_name) = &sess.opts.crate_name {
- format!("`cargo clean -p {}` or `cargo clean`", crate_name)
+ format!("`cargo clean -p {crate_name}` or `cargo clean`")
} else {
"`cargo clean`".to_string()
};
sess.emit_err(crate::error::IncrementCompilation {
run_cmd,
- dep_node: format!("{:?}", dep_node),
+ dep_node: format!("{dep_node:?}"),
});
- panic!("Found unstable fingerprints for {:?}: {:?}", dep_node, result);
+ panic!("Found unstable fingerprints for {dep_node:?}: {result:?}");
}
INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.set(old_in_panic));
if seg.res != Res::Err {
seg.res
} else {
- let parent_node = self.tcx.hir().get_parent_node(hir_id);
+ let parent_node = self.tcx.hir().parent_id(hir_id);
self.get_path_res(parent_node)
}
}
SplitDebuginfo,
}
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub enum TraitSolver {
+ /// Classic trait solver in `rustc_trait_selection::traits::select`
+ Classic,
+ /// Chalk trait solver
+ Chalk,
+ /// Experimental trait solver in `rustc_trait_selection::solve`
+ Next,
+}
+
pub enum Input {
/// Load source code from a file.
File(PathBuf),
BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, ErrorOutputType,
InstrumentCoverage, LdImpl, LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel,
OutputType, OutputTypes, Passes, SourceFileHashAlgorithm, SplitDwarfKind,
- SwitchWithOptPath, SymbolManglingVersion, TrimmedDefPaths,
+ SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
};
use crate::lint;
use crate::options::WasiExecModel;
BranchProtection,
OomStrategy,
LanguageIdentifier,
+ TraitSolver,
);
impl<T1, T2> DepTrackingHash for (T1, T2)
"`all` (default), `except-unused-generics`, `except-unused-functions`, or `off`";
pub const parse_unpretty: &str = "`string` or `string=string`";
pub const parse_treat_err_as_bug: &str = "either no value or a number bigger than 0";
+ pub const parse_trait_solver: &str =
+ "one of the supported solver modes (`classic`, `chalk`, or `next`)";
pub const parse_lto: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted";
pub const parse_linker_plugin_lto: &str =
}
}
+ pub(crate) fn parse_trait_solver(slot: &mut TraitSolver, v: Option<&str>) -> bool {
+ match v {
+ Some("classic") => *slot = TraitSolver::Classic,
+ Some("chalk") => *slot = TraitSolver::Chalk,
+ Some("next") => *slot = TraitSolver::Next,
+ // default trait solver is subject to change..
+ Some("default") => *slot = TraitSolver::Classic,
+ _ => return false,
+ }
+ true
+ }
+
pub(crate) fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool {
if v.is_some() {
let mut bool_arg = None;
"instrument control-flow architecture protection"),
cgu_partitioning_strategy: Option<String> = (None, parse_opt_string, [TRACKED],
"the codegen unit partitioning strategy to use"),
- chalk: bool = (false, parse_bool, [TRACKED],
- "enable the experimental Chalk-based trait solving engine"),
codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED],
"the backend to use"),
combine_cgu: bool = (false, parse_bool, [TRACKED],
"for every macro invocation, print its name and arguments (default: no)"),
track_diagnostics: bool = (false, parse_bool, [UNTRACKED],
"tracks where in rustc a diagnostic was emitted"),
+ trait_solver: TraitSolver = (TraitSolver::Classic, parse_trait_solver, [TRACKED],
+ "specify the trait solver mode used by rustc (default: classic)"),
// Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved
// alongside query results and changes to translation options can affect diagnostics - so
// translation options should be tracked.
// i.e. don't use closures.
match self.as_local() {
Some(local_def_id) => local_def_id,
- None => panic!("DefId::expect_local: `{:?}` isn't local", self),
+ None => panic!("DefId::expect_local: `{self:?}` isn't local"),
}
}
Edition::Edition2021 => "2021",
Edition::Edition2024 => "2024",
};
- write!(f, "{}", s)
+ write!(f, "{s}")
}
}
// Such configuration must not be used for metadata.
HashingControls { hash_spans }
if hash_spans == !ctx.unstable_opts_incremental_ignore_spans() => {}
- other => panic!("Attempted hashing of {msg} with non-default HashingControls: {:?}", other),
+ other => panic!("Attempted hashing of {msg} with non-default HashingControls: {other:?}"),
}
}
pub fn debug_hygiene_data(verbose: bool) -> String {
HygieneData::with(|data| {
if verbose {
- format!("{:#?}", data)
+ format!("{data:#?}")
} else {
let mut s = String::from("Expansions:");
let mut debug_expn_data = |(id, expn_data): (&ExpnId, &ExpnData)| {
match *self {
ExpnKind::Root => kw::PathRoot.to_string(),
ExpnKind::Macro(macro_kind, name) => match macro_kind {
- MacroKind::Bang => format!("{}!", name),
- MacroKind::Attr => format!("#[{}]", name),
- MacroKind::Derive => format!("#[derive({})]", name),
+ MacroKind::Bang => format!("{name}!"),
+ MacroKind::Attr => format!("#[{name}]"),
+ MacroKind::Derive => format!("#[derive({name})]"),
},
ExpnKind::AstPass(kind) => kind.descr().to_string(),
ExpnKind::Desugaring(kind) => format!("desugaring of {}", kind.descr()),
/// collisions are only possible between `ExpnId`s within the same crate.
fn update_disambiguator(expn_data: &mut ExpnData, mut ctx: impl HashStableContext) -> ExpnHash {
// This disambiguator should not have been set yet.
- assert_eq!(
- expn_data.disambiguator, 0,
- "Already set disambiguator for ExpnData: {:?}",
- expn_data
- );
+ assert_eq!(expn_data.disambiguator, 0, "Already set disambiguator for ExpnData: {expn_data:?}");
assert_default_hashing_controls(&ctx, "ExpnData (disambiguator)");
let mut expn_hash = expn_data.hash_expn(&mut ctx);
ProcMacroSourceCode(_) => write!(fmt, "<proc-macro source code>"),
CfgSpec(_) => write!(fmt, "<cfgspec>"),
CliCrateAttr(_) => write!(fmt, "<crate attribute>"),
- Custom(ref s) => write!(fmt, "<{}>", s),
+ Custom(ref s) => write!(fmt, "<{s}>"),
DocTest(ref path, _) => write!(fmt, "{}", path.display()),
InlineAsm(_) => write!(fmt, "<inline asm>"),
}
0 => NonNarrowChar::ZeroWidth(pos),
2 => NonNarrowChar::Wide(pos),
4 => NonNarrowChar::Tab(pos),
- _ => panic!("width {} given for non-narrow character", width),
+ _ => panic!("width {width} given for non-narrow character"),
}
}
if let Some(source_map) = &*session_globals.source_map.borrow() {
source_map.span_to_embeddable_string(span)
} else {
- format!("{:?}", span)
+ format!("{span:?}")
}
});
self.record_arg(span_arg);
fn finish(mut self, hash: u64) -> String {
self.finalize_pending_component();
// E = end name-sequence
- let _ = write!(self.result, "17h{:016x}E", hash);
+ let _ = write!(self.result, "17h{hash:016x}E");
self.result
}
}
self = self.print_type(ty)?;
self.write_str("; ")?;
if let Some(size) = size.kind().try_to_bits(self.tcx().data_layout.pointer_size) {
- write!(self, "{}", size)?
+ write!(self, "{size}")?
} else if let ty::ConstKind::Param(param) = size.kind() {
self = param.print(self)?
} else {
debug_assert!(
rustc_demangle::try_demangle(&symbol).is_ok(),
- "compute_symbol_name: `{}` cannot be demangled",
- symbol
+ "compute_symbol_name: `{symbol}` cannot be demangled"
);
symbol
tcx.sess.emit_err(TestOutput {
span: attr.span,
kind: Kind::DemanglingAlt,
- content: format!("{:#}", demangling),
+ content: format!("{demangling:#}"),
});
}
}
if value < zero {
s.push('n')
};
- let _ = write!(s, "{}", value);
+ let _ = write!(s, "{value}");
}
fn push_unsigned_value<T: Display>(s: &mut String, value: T) {
- let _ = write!(s, "{}", value);
+ let _ = write!(s, "{value}");
}
if let Some(scalar_int) = c.kind().try_to_scalar_int() {
bits = val.unsigned_abs();
}
- let _ = write!(self.out, "{:x}_", bits);
+ let _ = write!(self.out, "{bits:x}_");
}
// FIXME(valtrees): Remove the special case for `str`
// FIXME(eddyb) use a specialized hex-encoding loop.
for byte in s.bytes() {
- let _ = write!(self.out, "{:02x}", byte);
+ let _ = write!(self.out, "{byte:02x}");
}
self.push("_");
17..=32 => dl.i32_align.abi,
33..=64 => dl.i64_align.abi,
65..=128 => dl.i128_align.abi,
- _ => panic!("unsupported integer: {:?}", self),
+ _ => panic!("unsupported integer: {self:?}"),
},
RegKind::Float => match self.size.bits() {
32 => dl.f32_align.abi,
64 => dl.f64_align.abi,
- _ => panic!("unsupported float: {:?}", self),
+ _ => panic!("unsupported float: {self:?}"),
},
RegKind::Vector => dl.vector_align(self.size).abi,
}
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Unsupported { arch, abi } => {
- write!(f, "target architecture {:?} does not support `extern {}` ABI", arch, abi)
+ write!(f, "target architecture {arch:?} does not support `extern {abi}` ABI")
}
}
}
"AmdGpuKernel" => Ok(Conv::AmdGpuKernel),
"AvrInterrupt" => Ok(Conv::AvrInterrupt),
"AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt),
- _ => Err(format!("'{}' is not a valid value for entry function call convetion.", s)),
+ _ => Err(format!("'{s}' is not a valid value for entry function call convetion.")),
}
}
}
(modifier.unwrap_or('v'), self as u32 - Self::v0 as u32)
};
assert!(index < 32);
- write!(out, "{}{}", prefix, index)
+ write!(out, "{prefix}{index}")
}
}
let index = self as u32 - Self::q0 as u32;
assert!(index < 16);
let index = index * 2 + (modifier == 'f') as u32;
- write!(out, "d{}", index)
+ write!(out, "d{index}")
} else {
out.write_str(self.name())
}
Self::I128 => f.write_str("i128"),
Self::F32 => f.write_str("f32"),
Self::F64 => f.write_str("f64"),
- Self::VecI8(n) => write!(f, "i8x{}", n),
- Self::VecI16(n) => write!(f, "i16x{}", n),
- Self::VecI32(n) => write!(f, "i32x{}", n),
- Self::VecI64(n) => write!(f, "i64x{}", n),
- Self::VecI128(n) => write!(f, "i128x{}", n),
- Self::VecF32(n) => write!(f, "f32x{}", n),
- Self::VecF64(n) => write!(f, "f64x{}", n),
+ Self::VecI8(n) => write!(f, "i8x{n}"),
+ Self::VecI16(n) => write!(f, "i16x{n}"),
+ Self::VecI32(n) => write!(f, "i32x{n}"),
+ Self::VecI64(n) => write!(f, "i64x{n}"),
+ Self::VecI128(n) => write!(f, "i128x{n}"),
+ Self::VecF32(n) => write!(f, "f32x{n}"),
+ Self::VecF64(n) => write!(f, "f64x{n}"),
}
}
}
if self as u32 <= Self::dx as u32 {
let root = ['a', 'b', 'c', 'd'][self as usize - Self::ax as usize];
match modifier.unwrap_or(reg_default_modifier) {
- 'l' => write!(out, "{}l", root),
- 'h' => write!(out, "{}h", root),
- 'x' => write!(out, "{}x", root),
- 'e' => write!(out, "e{}x", root),
- 'r' => write!(out, "r{}x", root),
+ 'l' => write!(out, "{root}l"),
+ 'h' => write!(out, "{root}h"),
+ 'x' => write!(out, "{root}x"),
+ 'e' => write!(out, "e{root}x"),
+ 'r' => write!(out, "r{root}x"),
_ => unreachable!(),
}
} else if self as u32 <= Self::di as u32 {
let root = self.name();
match modifier.unwrap_or(reg_default_modifier) {
- 'l' => write!(out, "{}l", root),
- 'x' => write!(out, "{}", root),
- 'e' => write!(out, "e{}", root),
- 'r' => write!(out, "r{}", root),
+ 'l' => write!(out, "{root}l"),
+ 'x' => write!(out, "{root}"),
+ 'e' => write!(out, "e{root}"),
+ 'r' => write!(out, "r{root}"),
_ => unreachable!(),
}
} else if self as u32 <= Self::r15 as u32 {
let root = self.name();
match modifier.unwrap_or(reg_default_modifier) {
- 'l' => write!(out, "{}b", root),
- 'x' => write!(out, "{}w", root),
- 'e' => write!(out, "{}d", root),
+ 'l' => write!(out, "{root}b"),
+ 'x' => write!(out, "{root}w"),
+ 'e' => write!(out, "{root}d"),
'r' => out.write_str(root),
_ => unreachable!(),
}
} else if self as u32 <= Self::xmm15 as u32 {
let prefix = modifier.unwrap_or('x');
let index = self as u32 - Self::xmm0 as u32;
- write!(out, "{}{}", prefix, index)
+ write!(out, "{prefix}{index}")
} else if self as u32 <= Self::ymm15 as u32 {
let prefix = modifier.unwrap_or('y');
let index = self as u32 - Self::ymm0 as u32;
- write!(out, "{}{}", prefix, index)
+ write!(out, "{prefix}{index}")
} else if self as u32 <= Self::zmm31 as u32 {
let prefix = modifier.unwrap_or('z');
let index = self as u32 - Self::zmm0 as u32;
- write!(out, "{}{}", prefix, index)
+ write!(out, "{prefix}{index}")
} else {
out.write_str(self.name())
}
fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
let platform_name: StaticCow<str> = match abi {
- "sim" => format!("{}-simulator", os).into(),
+ "sim" => format!("{os}-simulator").into(),
"macabi" => "mac-catalyst".into(),
_ => os.into(),
};
fn macos_lld_platform_version(arch: Arch) -> String {
let (major, minor) = macos_deployment_target(arch);
- format!("{}.{}", major, minor)
+ format!("{major}.{minor}")
}
pub fn macos_llvm_target(arch: Arch) -> String {
fn ios_lld_platform_version() -> String {
let (major, minor) = ios_deployment_target();
- format!("{}.{}", major, minor)
+ format!("{major}.{minor}")
}
pub fn ios_sim_llvm_target(arch: Arch) -> String {
fn tvos_lld_platform_version() -> String {
let (major, minor) = tvos_deployment_target();
- format!("{}.{}", major, minor)
+ format!("{major}.{minor}")
}
fn watchos_deployment_target() -> (u32, u32) {
fn watchos_lld_platform_version() -> String {
let (major, minor) = watchos_deployment_target();
- format!("{}.{}", major, minor)
+ format!("{major}.{minor}")
}
pub fn watchos_sim_llvm_target(arch: Arch) -> String {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut first = true;
for s in *self {
- let name = s.as_str().unwrap_or_else(|| panic!("unrecognized sanitizer {:?}", s));
+ let name = s.as_str().unwrap_or_else(|| panic!("unrecognized sanitizer {s:?}"));
if !first {
f.write_str(", ")?;
}
let mut get_req_field = |name: &str| {
obj.remove(name)
.and_then(|j| j.as_str().map(str::to_string))
- .ok_or_else(|| format!("Field {} in target specification is required", name))
+ .ok_or_else(|| format!("Field {name} in target specification is required"))
};
let mut base = Target {
if let Some(s) = fp.as_str() {
base.frame_pointer = s
.parse()
- .map_err(|()| format!("'{}' is not a valid value for frame-pointer", s))?;
+ .map_err(|()| format!("'{s}' is not a valid value for frame-pointer"))?;
} else {
incorrect_type.push("frame-pointer".into())
}
return load_file(&p);
}
- Err(format!("Could not find specification for target {:?}", target_triple))
+ Err(format!("Could not find specification for target {target_triple:?}"))
}
TargetTriple::TargetJson { ref contents, .. } => {
let obj = serde_json::from_str(contents).map_err(|e| e.to_string())?;
let contents = std::fs::read_to_string(&canonicalized_path).map_err(|err| {
io::Error::new(
io::ErrorKind::InvalidInput,
- format!("target path {:?} is not a valid file: {}", canonicalized_path, err),
+ format!("target path {canonicalized_path:?} is not a valid file: {err}"),
)
})?;
let triple = canonicalized_path
let mut hasher = DefaultHasher::new();
content.hash(&mut hasher);
let hash = hasher.finish();
- format!("{}-{}", triple, hash)
+ format!("{triple}-{hash}")
}
}
}
pub fn opts(kernel: &str) -> TargetOptions {
TargetOptions {
- os: format!("solid_{}", kernel).into(),
+ os: format!("solid_{kernel}").into(),
vendor: "kmc".into(),
executables: false,
frame_pointer: FramePointer::NonLeaf,
use super::TraitEngine;
use super::{ChalkFulfillmentContext, FulfillmentContext};
+use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt;
use crate::traits::NormalizeExt;
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::ToPredicate;
use rustc_middle::ty::TypeFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_session::config::TraitSolver;
use rustc_span::Span;
pub trait TraitEngineExt<'tcx> {
impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
fn new(tcx: TyCtxt<'tcx>) -> Box<Self> {
- if tcx.sess.opts.unstable_opts.chalk {
- Box::new(ChalkFulfillmentContext::new())
- } else {
- Box::new(FulfillmentContext::new())
+ match tcx.sess.opts.unstable_opts.trait_solver {
+ TraitSolver::Classic => Box::new(FulfillmentContext::new()),
+ TraitSolver::Chalk => Box::new(ChalkFulfillmentContext::new()),
+ TraitSolver::Next => Box::new(NextFulfillmentCtxt::new()),
}
}
fn new_in_snapshot(tcx: TyCtxt<'tcx>) -> Box<Self> {
- if tcx.sess.opts.unstable_opts.chalk {
- Box::new(ChalkFulfillmentContext::new_in_snapshot())
- } else {
- Box::new(FulfillmentContext::new_in_snapshot())
+ match tcx.sess.opts.unstable_opts.trait_solver {
+ TraitSolver::Classic => Box::new(FulfillmentContext::new_in_snapshot()),
+ TraitSolver::Chalk => Box::new(ChalkFulfillmentContext::new_in_snapshot()),
+ TraitSolver::Next => Box::new(NextFulfillmentCtxt::new()),
}
}
}
use rustc_infer::infer::{InferOk, TypeTrace};
use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
-use rustc_middle::ty::error::ExpectedFound;
+use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print};
use rustc_middle::ty::{
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
TypeVisitable,
};
+use rustc_session::config::TraitSolver;
use rustc_session::Limit;
use rustc_span::def_id::LOCAL_CRATE;
use rustc_span::symbol::sym;
}
ty::PredicateKind::WellFormed(ty) => {
- if !self.tcx.sess.opts.unstable_opts.chalk {
+ if self.tcx.sess.opts.unstable_opts.trait_solver != TraitSolver::Chalk {
// WF predicates cannot themselves make
// errors. They can only block due to
// ambiguity; otherwise, they always
}
}
+ OutputTypeParameterMismatch(
+ found_trait_ref,
+ expected_trait_ref,
+ terr @ TypeError::CyclicTy(_),
+ ) => {
+ let self_ty = found_trait_ref.self_ty().skip_binder();
+ let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() {
+ (
+ ObligationCause::dummy_with_span(tcx.def_span(def_id)),
+ TypeError::CyclicTy(self_ty),
+ )
+ } else {
+ (obligation.cause.clone(), terr)
+ };
+ self.report_and_explain_type_error(
+ TypeTrace::poly_trait_refs(&cause, true, expected_trait_ref, found_trait_ref),
+ terr,
+ )
+ }
OutputTypeParameterMismatch(found_trait_ref, expected_trait_ref, _) => {
let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref);
let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref);
Some(if movability.is_some() { "an async closure" } else { "a closure" })
}),
hir::Node::Expr(hir::Expr { .. }) => {
- let parent_hid = hir.get_parent_node(hir_id);
+ let parent_hid = hir.parent_id(hir_id);
if parent_hid != hir_id { self.describe_enclosure(parent_hid) } else { None }
}
_ => None,
let hir = self.tcx.hir();
let hir_id = hir.local_def_id_to_hir_id(def_id.as_local()?);
- let parent_node = hir.get_parent_node(hir_id);
- match hir.find(parent_node) {
+ match hir.find_parent(hir_id) {
Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local), .. })) => {
get_name(err, &local.pat.kind)
}
trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool {
let hir = self.tcx.hir();
- let parent_node = hir.get_parent_node(obligation.cause.body_id);
+ let parent_node = hir.parent_id(obligation.cause.body_id);
let node = hir.find(parent_node);
if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })) = node
&& let hir::ExprKind::Block(blk, _) = &hir.body(*body_id).value.kind
fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> {
let hir = self.tcx.hir();
- let parent_node = hir.get_parent_node(obligation.cause.body_id);
+ let parent_node = hir.parent_id(obligation.cause.body_id);
let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) = hir.find(parent_node) else {
return None;
};
}
let hir = self.tcx.hir();
- let fn_hir_id = hir.get_parent_node(obligation.cause.body_id);
+ let fn_hir_id = hir.parent_id(obligation.cause.body_id);
let node = hir.find(fn_hir_id);
let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(sig, _, body_id),
}
let hir = self.tcx.hir();
- let parent_node = hir.get_parent_node(obligation.cause.body_id);
+ let parent_node = hir.parent_id(obligation.cause.body_id);
let node = hir.find(parent_node);
if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) =
node
let expr = hir.expect_expr(expr_id);
debug!("target_ty evaluated from {:?}", expr);
- let parent = hir.get_parent_node(expr_id);
+ let parent = hir.parent_id(expr_id);
if let Some(hir::Node::Expr(e)) = hir.find(parent) {
let parent_span = hir.span(parent);
let parent_did = parent.owner.to_def_id();
}
}
ObligationCauseCode::VariableType(hir_id) => {
- let parent_node = self.tcx.hir().get_parent_node(hir_id);
+ let parent_node = self.tcx.hir().parent_id(hir_id);
match self.tcx.hir().find(parent_node) {
Some(Node::Local(hir::Local { ty: Some(ty), .. })) => {
err.span_suggestion_verbose(
span: Span,
) {
let body_hir_id = obligation.cause.body_id;
- let item_id = self.tcx.hir().get_parent_node(body_hir_id);
+ let item_id = self.tcx.hir().parent_id(body_hir_id);
if let Some(body_id) =
self.tcx.hir().maybe_body_owned_by(self.tcx.hir().local_def_id(item_id))
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
&& let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
- && let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id)
+ && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id)
&& let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id)
&& let Some(binding_expr) = local.init
{
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
&& let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
- && let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id)
- && let Some(parent) = self.tcx.hir().find(parent_hir_id)
+ && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
{
// We've reached the root of the method call chain...
if let hir::Node::Local(local) = parent
self, Binder, GenericArg, GenericArgKind, GenericParamDefKind, InternalSubsts, SubstsRef,
ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt,
};
+use rustc_session::config::TraitSolver;
use rustc_span::def_id::DefId;
use crate::traits::project::{normalize_with_depth, normalize_with_depth_to};
debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations");
// FIXME: Chalk
-
- if !self.tcx().sess.opts.unstable_opts.chalk {
+ if self.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Chalk {
nested.push(obligation.with(
self.tcx(),
ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)),
tcx.sess.delay_span_bug(
span,
- &format!("upvar_tys for closure not found. Expected capture information for closure {}", ty,),
+ &format!("upvar_tys for closure not found. Expected capture information for closure {ty}",),
);
return Err(NoSolution);
}
// be fully resolved.
tcx.sess.delay_span_bug(
span,
- &format!("upvar_tys for generator not found. Expected capture information for generator {}", ty,),
+ &format!("upvar_tys for generator not found. Expected capture information for generator {ty}",),
);
return Err(NoSolution);
}
// us a test case.
debug_assert_eq!(normalized_value, resolved_value);
let erased = infcx.tcx.erase_regions(resolved_value);
- debug_assert!(!erased.needs_infer(), "{:?}", erased);
+ debug_assert!(!erased.needs_infer(), "{erased:?}");
Ok(erased)
}
Err(NoSolution) => Err(NoSolution),
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self {
Self::Uninit => f.write_str("??u8"),
- Self::Init(b) => write!(f, "{:#04x}u8", b),
+ Self::Init(b) => write!(f, "{b:#04x}u8"),
}
}
}
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt};
+use rustc_session::config::TraitSolver;
use rustc_trait_selection::traits;
fn sized_constraint_for_ty<'tcx>(
// are any errors at that point, so outside of type inference you can be
// sure that this will succeed without errors anyway.
- if tcx.sess.opts.unstable_opts.chalk {
+ if tcx.sess.opts.unstable_opts.trait_solver == TraitSolver::Chalk {
let environment = well_formed_types_in_env(tcx, def_id);
predicates.extend(environment);
}
kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..),
..
}) => {
- let parent_hir_id = tcx.hir().get_parent_node(hir_id);
+ let parent_hir_id = tcx.hir().parent_id(hir_id);
match tcx.hir().get(parent_hir_id) {
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
TyVar(ref v) => v.fmt(f),
IntVar(ref v) => v.fmt(f),
FloatVar(ref v) => v.fmt(f),
- FreshTy(v) => write!(f, "FreshTy({:?})", v),
- FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
- FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v),
+ FreshTy(v) => write!(f, "FreshTy({v:?})"),
+ FreshIntTy(v) => write!(f, "FreshIntTy({v:?})"),
+ FreshFloatTy(v) => write!(f, "FreshFloatTy({v:?})"),
}
}
}
TyVar(_) => write!(f, "_"),
IntVar(_) => write!(f, "{}", "{integer}"),
FloatVar(_) => write!(f, "{}", "{float}"),
- FreshTy(v) => write!(f, "FreshTy({})", v),
- FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
- FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v),
+ FreshTy(v) => write!(f, "FreshTy({v})"),
+ FreshIntTy(v) => write!(f, "FreshIntTy({v})"),
+ FreshFloatTy(v) => write!(f, "FreshFloatTy({v})"),
}
}
}
impl<I: Interner> fmt::Debug for RegionKind<I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
- ReEarlyBound(data) => write!(f, "ReEarlyBound({:?})", data),
+ ReEarlyBound(data) => write!(f, "ReEarlyBound({data:?})"),
ReLateBound(binder_id, bound_region) => {
- write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
+ write!(f, "ReLateBound({binder_id:?}, {bound_region:?})")
}
ReFree(fr) => fr.fmt(f),
ReVar(vid) => vid.fmt(f),
- RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
+ RePlaceholder(placeholder) => write!(f, "RePlaceholder({placeholder:?})"),
ReErased => f.write_str("ReErased"),
}
//! # How to read this documentation
//!
//! If you already know the name of what you are looking for, the fastest way to
-//! find it is to use the <a href="#" onclick="focusSearchBar();">search
+//! find it is to use the <a href="#" onclick="window.searchState.focus();">search
//! bar</a> at the top of the page.
//!
//! Otherwise, you may want to jump to one of these useful sections:
let mut ntest = 0;
let mut nbench = 0;
- for test in filter_tests(&opts, tests).into_iter() {
+ for test in filter_tests(opts, tests).into_iter() {
use crate::TestFn::*;
let TestDescAndFn { desc: TestDesc { name, .. }, testfn } = test;
let stdout = &completed_test.stdout;
st.write_log_result(test, result, exec_time.as_ref())?;
- out.write_result(test, result, exec_time.as_ref(), &*stdout, st)?;
+ out.write_result(test, result, exec_time.as_ref(), stdout, st)?;
handle_test_result(st, completed_test);
}
}
let max_name_len = tests
.iter()
- .max_by_key(|t| len_if_padded(*t))
+ .max_by_key(|t| len_if_padded(t))
.map(|t| t.desc.name.as_slice().len())
.unwrap_or(0);
extra: Option<&str>,
) -> io::Result<()> {
// A doc test's name includes a filename which must be escaped for correct json.
- self.write_message(&*format!(
+ self.write_message(&format!(
r#"{{ "type": "{}", "name": "{}", "event": "{}""#,
ty,
EscapedString(name),
evt
))?;
if let Some(exec_time) = exec_time {
- self.write_message(&*format!(r#", "exec_time": {}"#, exec_time.0.as_secs_f64()))?;
+ self.write_message(&format!(r#", "exec_time": {}"#, exec_time.0.as_secs_f64()))?;
}
if let Some(stdout) = stdout {
- self.write_message(&*format!(r#", "stdout": "{}""#, EscapedString(stdout)))?;
+ self.write_message(&format!(r#", "stdout": "{}""#, EscapedString(stdout)))?;
}
if let Some(extra) = extra {
- self.write_message(&*format!(r#", {extra}"#))?;
+ self.write_message(&format!(r#", {extra}"#))?;
}
self.writeln_message(" }")
}
} else {
String::new()
};
- self.writeln_message(&*format!(
+ self.writeln_message(&format!(
r#"{{ "type": "suite", "event": "started", "test_count": {test_count}{shuffle_seed_json} }}"#
))
}
fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
- self.writeln_message(&*format!(
+ self.writeln_message(&format!(
r#"{{ "type": "test", "event": "started", "name": "{}" }}"#,
EscapedString(desc.name.as_slice())
))
mbps
);
- self.writeln_message(&*line)
+ self.writeln_message(&line)
}
}
}
fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
- self.writeln_message(&*format!(
+ self.writeln_message(&format!(
r#"{{ "type": "test", "event": "timeout", "name": "{}" }}"#,
EscapedString(desc.name.as_slice())
))
}
fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
- self.write_message(&*format!(
+ self.write_message(&format!(
"{{ \"type\": \"suite\", \
\"event\": \"{}\", \
\"passed\": {}, \
fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
self.write_message("<testsuites>")?;
- self.write_message(&*format!(
+ self.write_message(&format!(
"<testsuite name=\"test\" package=\"test\" id=\"0\" \
errors=\"0\" \
failures=\"{}\" \
>",
state.failed, state.total, state.ignored
))?;
- for (desc, result, duration) in std::mem::replace(&mut self.results, Vec::new()) {
+ for (desc, result, duration) in std::mem::take(&mut self.results) {
let (class_name, test_name) = parse_class_name(&desc);
match result {
TestResult::TrIgnored => { /* no-op */ }
TestResult::TrFailed => {
- self.write_message(&*format!(
+ self.write_message(&format!(
"<testcase classname=\"{}\" \
name=\"{}\" time=\"{}\">",
class_name,
}
TestResult::TrFailedMsg(ref m) => {
- self.write_message(&*format!(
+ self.write_message(&format!(
"<testcase classname=\"{}\" \
name=\"{}\" time=\"{}\">",
class_name,
test_name,
duration.as_secs_f64()
))?;
- self.write_message(&*format!("<failure message=\"{m}\" type=\"assert\"/>"))?;
+ self.write_message(&format!("<failure message=\"{m}\" type=\"assert\"/>"))?;
self.write_message("</testcase>")?;
}
TestResult::TrTimedFail => {
- self.write_message(&*format!(
+ self.write_message(&format!(
"<testcase classname=\"{}\" \
name=\"{}\" time=\"{}\">",
class_name,
}
TestResult::TrBench(ref b) => {
- self.write_message(&*format!(
+ self.write_message(&format!(
"<testcase classname=\"benchmark::{}\" \
name=\"{}\" time=\"{}\" />",
class_name, test_name, b.ns_iter_summ.sum
}
TestResult::TrOk => {
- self.write_message(&*format!(
+ self.write_message(&format!(
"<testcase classname=\"{}\" \
name=\"{}\" time=\"{}\"/>",
class_name,
let mut results = Vec::new();
let mut stdouts = String::new();
- for &(ref f, ref stdout) in inputs {
+ for (f, stdout) in inputs {
results.push(f.name.to_string());
if !stdout.is_empty() {
stdouts.push_str(&format!("---- {} stdout ----\n", f.name));
fn write_test_name(&mut self, desc: &TestDesc) -> io::Result<()> {
let name = desc.padded_name(self.max_name_len, desc.name.padding());
if let Some(test_mode) = desc.test_mode() {
- self.write_plain(&format!("test {name} - {test_mode} ... "))?;
+ self.write_plain(format!("test {name} - {test_mode} ... "))?;
} else {
- self.write_plain(&format!("test {name} ... "))?;
+ self.write_plain(format!("test {name} ... "))?;
}
Ok(())
} else {
String::new()
};
- self.write_plain(&format!("\nrunning {test_count} {noun}{shuffle_seed_msg}\n"))
+ self.write_plain(format!("\nrunning {test_count} {noun}{shuffle_seed_msg}\n"))
}
fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
TestResult::TrIgnored => self.write_ignored(desc.ignore_message)?,
TestResult::TrBench(ref bs) => {
self.write_bench()?;
- self.write_plain(&format!(": {}", fmt_bench_samples(bs)))?;
+ self.write_plain(format!(": {}", fmt_bench_samples(bs)))?;
}
TestResult::TrTimedFail => self.write_time_failed()?,
}
}
fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
- self.write_plain(&format!(
+ self.write_plain(format!(
"test {} has been running for over {} seconds\n",
desc.name,
time::TEST_WARN_TIMEOUT_S
state.passed, state.failed, state.ignored, state.measured, state.filtered_out
);
- self.write_plain(&s)?;
+ self.write_plain(s)?;
if let Some(ref exec_time) = state.exec_time {
let time_str = format!("; finished in {exec_time}");
- self.write_plain(&time_str)?;
+ self.write_plain(time_str)?;
}
self.write_plain("\n\n")?;
// screen when dealing with line-buffered output (e.g., piping to
// `stamp` in the rust CI).
let out = format!(" {}/{}\n", self.test_count + 1, self.total_test_count);
- self.write_plain(&out)?;
+ self.write_plain(out)?;
}
self.test_count += 1;
self.write_plain("\nsuccesses:\n")?;
let mut successes = Vec::new();
let mut stdouts = String::new();
- for &(ref f, ref stdout) in &state.not_failures {
+ for (f, stdout) in &state.not_failures {
successes.push(f.name.to_string());
if !stdout.is_empty() {
stdouts.push_str(&format!("---- {} stdout ----\n", f.name));
self.write_plain("\nfailures:\n")?;
let mut failures = Vec::new();
let mut fail_out = String::new();
- for &(ref f, ref stdout) in &state.failures {
+ for (f, stdout) in &state.failures {
failures.push(f.name.to_string());
if !stdout.is_empty() {
fail_out.push_str(&format!("---- {} stdout ----\n", f.name));
fn write_test_name(&mut self, desc: &TestDesc) -> io::Result<()> {
let name = desc.padded_name(self.max_name_len, desc.name.padding());
if let Some(test_mode) = desc.test_mode() {
- self.write_plain(&format!("test {name} - {test_mode} ... "))?;
+ self.write_plain(format!("test {name} - {test_mode} ... "))?;
} else {
- self.write_plain(&format!("test {name} ... "))?;
+ self.write_plain(format!("test {name} ... "))?;
}
Ok(())
} else {
String::new()
};
- self.write_plain(&format!("\nrunning {test_count} {noun}{shuffle_seed_msg}\n"))
+ self.write_plain(format!("\nrunning {test_count} {noun}{shuffle_seed_msg}\n"))
}
fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
self.write_test_name(desc)?;
}
self.write_bench()?;
- self.write_plain(&format!(": {}\n", fmt_bench_samples(bs)))
+ self.write_plain(format!(": {}\n", fmt_bench_samples(bs)))
}
}
}
fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
- self.write_plain(&format!(
+ self.write_plain(format!(
"test {} has been running for over {} seconds\n",
desc.name,
time::TEST_WARN_TIMEOUT_S
state.passed, state.failed, state.ignored, state.measured, state.filtered_out
);
- self.write_plain(&s)?;
+ self.write_plain(s)?;
if let Some(ref exec_time) = state.exec_time {
let time_str = format!("; finished in {exec_time}");
- self.write_plain(&time_str)?;
+ self.write_plain(time_str)?;
}
self.write_plain("\n\n")?;
}
});
let record_result2 = record_result.clone();
- panic::set_hook(Box::new(move |info| record_result2(Some(&info))));
+ panic::set_hook(Box::new(move |info| record_result2(Some(info))));
if let Err(message) = testfn() {
panic!("{}", message);
}
// are there any terminals that have color/attrs and not sgr0?
// Try falling back to sgr, then op
let cmd = match ["sgr0", "sgr", "op"].iter().find_map(|cap| self.ti.strings.get(*cap)) {
- Some(op) => match expand(&op, &[], &mut Variables::new()) {
+ Some(op) => match expand(op, &[], &mut Variables::new()) {
Ok(cmd) => cmd,
Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)),
},
}
fn dim_if_necessary(&self, color: color::Color) -> color::Color {
- if color >= self.num_colors && color >= 8 && color < 16 { color - 8 } else { color }
+ if color >= self.num_colors && (8..16).contains(&color) { color - 8 } else { color }
}
fn apply_cap(&mut self, cmd: &str, params: &[Param]) -> io::Result<bool> {
match self.ti.strings.get(cmd) {
- Some(cmd) => match expand(&cmd, params, &mut Variables::new()) {
+ Some(cmd) => match expand(cmd, params, &mut Variables::new()) {
Ok(s) => self.out.write_all(&s).and(Ok(true)),
Err(e) => Err(io::Error::new(io::ErrorKind::InvalidData, e)),
},
);
}
SetVar => {
- if cur >= 'A' && cur <= 'Z' {
+ if cur.is_ascii_uppercase() {
if let Some(arg) = stack.pop() {
let idx = (cur as u8) - b'A';
vars.sta_va[idx as usize] = arg;
} else {
return Err("stack is empty".to_string());
}
- } else if cur >= 'a' && cur <= 'z' {
+ } else if cur.is_ascii_lowercase() {
if let Some(arg) = stack.pop() {
let idx = (cur as u8) - b'a';
vars.dyn_va[idx as usize] = arg;
}
}
GetVar => {
- if cur >= 'A' && cur <= 'Z' {
+ if cur.is_ascii_uppercase() {
let idx = (cur as u8) - b'A';
stack.push(vars.sta_va[idx as usize].clone());
- } else if cur >= 'a' && cur <= 'z' {
+ } else if cur.is_ascii_lowercase() {
let idx = (cur as u8) - b'a';
stack.push(vars.dyn_va[idx as usize].clone());
} else {
if let Ok(dirs) = env::var("TERMINFO_DIRS") {
for i in dirs.split(':') {
- if i == "" {
+ if i.is_empty() {
dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
} else {
dirs_to_search.push(PathBuf::from(i));
for mut p in dirs_to_search {
if fs::metadata(&p).is_ok() {
p.push(&first_char.to_string());
- p.push(&term);
+ p.push(term);
if fs::metadata(&p).is_ok() {
return Some(p);
}
) -> TestResult {
let result = match (&desc.should_panic, task_result) {
(&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TestResult::TrOk,
- (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => {
+ (&ShouldPanic::YesWithMessage(msg), Err(err)) => {
let maybe_panic_str = err
.downcast_ref::<String>()
.map(|e| &**e)
r#"expected panic with string value,
found non-string value: `{:?}`
expected substring: `{:?}`"#,
- (**err).type_id(),
+ (*err).type_id(),
msg
))
}
match *self {
StaticTestName(s) => s,
DynTestName(ref s) => s,
- AlignedTestName(ref s, _) => &*s,
+ AlignedTestName(ref s, _) => s,
}
}
[rust]
lld = true
+[llvm]
+download-ci-llvm = false
+
[target.x86_64-fuchsia]
cc = "clang"
cxx = "clang++"
.sub-logo-container, .logo-container {
/* zero text boxes so that computed line height = image height exactly */
line-height: 0;
+ display: block;
}
.sub-logo-container {
color: var(--sidebar-link-color);
}
.sidebar .current,
-.sidebar a:hover {
+.sidebar a:hover:not(.logo-container) {
background-color: var(--sidebar-current-link-background-color);
}
vertical-align: middle;
border: solid 1px var(--border-color);
border-radius: 3px;
- color: var(--kbd--color);
+ color: var(--kbd-color);
background-color: var(--kbd-background);
box-shadow: inset 0 -1px 0 var(--kbd-box-shadow-color);
}
/* Hide the logo and item name from the sidebar. Those are displayed
in the mobile-topbar instead. */
- .sidebar .sidebar-logo,
+ .sidebar .logo-container,
.sidebar .location {
display: none;
}
onEachLazy(code.getElementsByTagName("a"), elem => {
const href = elem.getAttribute("href");
- if (href && href.indexOf("http") !== 0) {
+ if (href && !/^(?:[a-z+]+:)?\/\//.test(href)) {
elem.setAttribute("href", window.rootPath + href);
}
});
help_button.appendChild(container);
container.onblur = helpBlurHandler;
- container.onclick = event => {
- event.preventDefault();
- };
help_button.onblur = helpBlurHandler;
help_button.children[0].onblur = helpBlurHandler;
}
{%- if page.css_class != "source" -%}
<nav class="mobile-topbar"> {#- -#}
<button class="sidebar-menu-toggle">☰</button> {#- -#}
- <a class="sidebar-logo" href="{{page.root_path|safe}}{{krate_with_trailing_slash|safe}}index.html"> {#- -#}
- <div class="logo-container"> {#- -#}
- {%- if !layout.logo.is_empty() -%}
- <img src="{{layout.logo}}" alt="logo"> {#- -#}
- {%- else -%}
- <img class="rust-logo" src="{{static_root_path|safe}}{{files.rust_logo_svg}}" alt="logo"> {#- -#}
- {%- endif -%}
- </div> {#- -#}
+ <a class="logo-container" href="{{page.root_path|safe}}{{krate_with_trailing_slash|safe}}index.html"> {#- -#}
+ {%- if !layout.logo.is_empty() -%}
+ <img src="{{layout.logo}}" alt="logo"> {#- -#}
+ {%- else -%}
+ <img class="rust-logo" src="{{static_root_path|safe}}{{files.rust_logo_svg}}" alt="logo"> {#- -#}
+ {%- endif -%}
</a> {#- -#}
<h2></h2> {#- -#}
</nav> {#- -#}
{%- endif -%}
<nav class="sidebar"> {#- -#}
{%- if page.css_class != "source" -%}
- <a class="sidebar-logo" href="{{page.root_path|safe}}{{krate_with_trailing_slash|safe}}index.html"> {#- -#}
- <div class="logo-container"> {#- -#}
- {%- if !layout.logo.is_empty() %}
- <img src="{{layout.logo}}" alt="logo"> {#- -#}
- {%- else -%}
- <img class="rust-logo" src="{{static_root_path|safe}}{{files.rust_logo_svg}}" alt="logo"> {#- -#}
- {%- endif -%}
- </div> {#- -#}
+ <a class="logo-container" href="{{page.root_path|safe}}{{krate_with_trailing_slash|safe}}index.html"> {#- -#}
+ {%- if !layout.logo.is_empty() %}
+ <img src="{{layout.logo}}" alt="logo"> {#- -#}
+ {%- else -%}
+ <img class="rust-logo" src="{{static_root_path|safe}}{{files.rust_logo_svg}}" alt="logo"> {#- -#}
+ {%- endif -%}
</a> {#- -#}
{%- endif -%}
{{- sidebar|safe -}}
use std::fmt;
use rustc_ast::ast;
-use rustc_hir::{def::CtorKind, def_id::DefId};
+use rustc_hir::{def::CtorKind, def::DefKind, def_id::DefId};
use rustc_middle::ty::{self, TyCtxt};
+use rustc_span::symbol::sym;
use rustc_span::{Pos, Symbol};
use rustc_target::spec::abi::Abi as RustcAbi;
impl<'a> fmt::Display for DisplayDefId<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let name = match self.2 {
+ let DisplayDefId(def_id, tcx, name) = self;
+ let name = match name {
Some(name) => format!(":{}", name.as_u32()),
- None => self
- .1
- .opt_item_name(self.0)
- .map(|n| format!(":{}", n.as_u32()))
- .unwrap_or_default(),
+ None => {
+ // We need this workaround because primitive types' DefId actually refers to
+ // their parent module, which isn't present in the output JSON items. So
+ // instead, we directly get the primitive symbol and convert it to u32 to
+ // generate the ID.
+ if matches!(tcx.def_kind(def_id), DefKind::Mod) &&
+ let Some(prim) = tcx.get_attrs(*def_id, sym::doc)
+ .flat_map(|attr| attr.meta_item_list().unwrap_or_default())
+ .filter(|attr| attr.has_name(sym::primitive))
+ .find_map(|attr| attr.value_str()) {
+ format!(":{}", prim.as_u32())
+ } else {
+ tcx
+ .opt_item_name(*def_id)
+ .map(|n| format!(":{}", n.as_u32()))
+ .unwrap_or_default()
+ }
+ }
};
write!(f, "{}:{}{}", self.0.krate.as_u32(), u32::from(self.0.index), name)
}
ItemId::Auto { for_, trait_ } => {
Id(format!("a:{}-{}", DisplayDefId(trait_, tcx, None), DisplayDefId(for_, tcx, name)))
}
- ItemId::Primitive(ty, krate) => Id(format!("p:{}:{}", krate.as_u32(), ty.as_sym())),
+ ItemId::Primitive(_, _) => unreachable!(),
}
}
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.item_id.expect_def_id().expect_local());
// check if parent is trait impl
- if let Some(parent_hir_id) = cx.tcx.hir().find_parent_node(hir_id) {
+ if let Some(parent_hir_id) = cx.tcx.hir().opt_parent_id(hir_id) {
if let Some(parent_node) = cx.tcx.hir().find(parent_hir_id) {
if matches!(
parent_node,
-Subproject commit 3dfd4d93fa013e1c0578d3ceac5c8f4ebba4b6ec
+Subproject commit 9ad24035fea8d309753f5e39e6eb53d1d0eb39ce
})
call-function: ("check-colors", {
"theme": "dark",
- "color": "rgb(221, 221, 221)",
+ "color": "rgb(0, 0, 0)",
"background": "rgb(250, 251, 252)",
"box_shadow": "rgb(198, 203, 209)",
})
assert-css: ("#help", {"display": "none"})
compare-elements-property-false: (".sub", "#help", ["offsetWidth"])
compare-elements-position-false: (".sub", "#help", ("x"))
+
+// This test ensures that the "the rustdoc book" anchor link within the help popover works.
+goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
+size: (1000, 1000) // Popover only appears when the screen width is >700px.
+assert-false: "#help"
+click: "#help-button > a"
+click: ".popover a[href='https://doc.rust-lang.org/rustdoc/']"
+wait-for: 2000
+assert-document-property: {"URL": "https://doc.rust-lang.org/rustdoc/"}
assert-count: ("#implementors-list .impl", 1)
goto: "file://" + |DOC_PATH| + "/implementors/trait.TraitToReexport.html"
assert-count: ("#implementors-list .impl", 1)
+
+// Now check that the link is properly rewritten for a crate called `http`.
+// An older version of rustdoc had a buggy check for absolute links.
+goto: "file://" + |DOC_PATH| + "/http/trait.HttpTrait.html"
+assert-count: ("#implementors-list .impl", 1)
+assert-attribute: ("#implementors-list .impl a.trait", {"href": "../http/trait.HttpTrait.html"})
press-key: "ArrowDown"
press-key: "ArrowDown"
press-key: "ArrowDown"
+press-key: "ArrowDown"
press-key: "Enter"
// Waiting for the search results to appear...
wait-for: "#search-tabs"
press-key: "ArrowUp"
press-key: "ArrowUp"
press-key: "ArrowUp"
+press-key: "ArrowUp"
press-key: "Enter"
// Waiting for the search results to appear...
wait-for: "#search-tabs"
// Only "another_folder" should be "open" in "lib2".
assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']"
// All other trees should be collapsed.
-assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 7)
+assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 8)
// We now switch to mobile mode.
size: (600, 600)
// We check that the first entry of the sidebar is collapsed
assert-property: ("#source-sidebar details:first-of-type", {"open": "false"})
-assert-text: ("#source-sidebar details:first-of-type > summary", "huge_logo")
+assert-text: ("#source-sidebar details:first-of-type > summary", "http")
// We now click on it.
click: "#source-sidebar details:first-of-type > summary"
assert-property: ("#source-sidebar details:first-of-type", {"open": "true"})
# It is not intended for manual editing.
version = 3
+[[package]]
+name = "http"
+version = "0.1.0"
+
[[package]]
name = "implementors"
version = "0.1.0"
+dependencies = [
+ "http",
+]
[[package]]
name = "lib2"
version = "0.1.0"
dependencies = [
+ "http",
"implementors",
]
[dependencies]
implementors = { path = "./implementors" }
+http = { path = "./http" }
--- /dev/null
+[package]
+name = "http"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
--- /dev/null
+pub trait HttpTrait {}
[lib]
path = "lib.rs"
+
+[dependencies]
+http = { path = "../http/" }
type Foo = u8;
}
+impl http::HttpTrait for Struct {}
+
mod traits {
pub trait TraitToReexport {
fn method() {}
--- /dev/null
+// Regression test for <https://github.com/rust-lang/rust/issues/104064>.
+
+#![feature(no_core)]
+#![feature(rustc_attrs)]
+#![feature(rustdoc_internals)]
+#![no_core]
+#![rustc_coherence_is_core]
+
+//! Link to [i32][prim@i32] [i64][prim@i64]
+
+#[doc(primitive = "i32")]
+mod prim_i32 {}
+
+// @set local_i32 = "$.index[*][?(@.name=='i32')].id"
+
+// @has "$.index[*][?(@.name=='local_primitive')]"
+// @ismany "$.index[*][?(@.name=='local_primitive')].inner.items[*]" $local_i32
+// @is "$.index[*][?(@.name=='local_primitive')].links['prim@i32']" $local_i32
+
+// Let's ensure the `prim_i32` module isn't present in the output JSON:
+// @!has "$.index[*][?(@.name=='prim_i32')]"
-Z branch-protection=val -- set options for branch target identification and pointer authentication on AArch64
-Z cf-protection=val -- instrument control-flow architecture protection
-Z cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use
- -Z chalk=val -- enable the experimental Chalk-based trait solving engine
-Z codegen-backend=val -- the backend to use
-Z combine-cgu=val -- combine CGUs into a single one
-Z crate-attr=val -- inject the given attribute in the crate
-Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details)
-Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no)
-Z track-diagnostics=val -- tracks where in rustc a diagnostic was emitted
+ -Z trait-solver=val -- specify the trait solver mode used by rustc (default: classic)
-Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation)
-Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics
-Z translate-lang=val -- language identifier for diagnostic output
struct Layout;
#[alloc_error_handler]
-fn oom() -> ! { //~ ERROR this function takes 0 arguments but 1 argument was supplied
+fn oom() -> ! { //~ ERROR function takes 0 arguments but 1 argument was supplied
loop {}
}
fn main() {
invalid(1.0); //~ ERROR mismatched types
- extra(""); //~ ERROR this function takes
- missing(); //~ ERROR this function takes
+ extra(""); //~ ERROR function takes
+ missing(); //~ ERROR function takes
swapped("", 1); //~ ERROR arguments to this function are incorrect
permuted(Y {}, Z {}, X {}); //~ ERROR arguments to this function are incorrect
let closure = |x| x;
- closure(); //~ ERROR this function takes
+ closure(); //~ ERROR function takes
}
fn main() {
foo();
- //~^ ERROR this function takes 1 argument but 0 arguments were supplied
+ //~^ ERROR function takes 1 argument but 0 arguments were supplied
}
fn foo<T: Fn()>(t: T) {
t(1i32);
- //~^ ERROR this function takes 0 arguments but 1 argument was supplied
+ //~^ ERROR function takes 0 arguments but 1 argument was supplied
}
fn bar(t: impl Fn()) {
t(1i32);
- //~^ ERROR this function takes 0 arguments but 1 argument was supplied
+ //~^ ERROR function takes 0 arguments but 1 argument was supplied
}
fn baz() -> impl Fn() {
fn baz2() {
baz()(1i32)
- //~^ ERROR this function takes 0 arguments but 1 argument was supplied
+ //~^ ERROR function takes 0 arguments but 1 argument was supplied
}
fn qux() {
let x = || {};
x(1i32);
- //~^ ERROR this function takes 0 arguments but 1 argument was supplied
+ //~^ ERROR function takes 0 arguments but 1 argument was supplied
}
fn main() {}
fn main() {
dstfn(1);
- //~^ ERROR this function takes 2 arguments but 1 argument was supplied
+ //~^ ERROR function takes 2 arguments but 1 argument was supplied
}
fn two_arg_diff(_a: i32, _b: &str) {}
fn main() {
- empty(""); //~ ERROR this function takes
+ empty(""); //~ ERROR function takes
- one_arg(1, 1); //~ ERROR this function takes
- one_arg(1, ""); //~ ERROR this function takes
- one_arg(1, "", 1.0); //~ ERROR this function takes
+ one_arg(1, 1); //~ ERROR function takes
+ one_arg(1, ""); //~ ERROR function takes
+ one_arg(1, "", 1.0); //~ ERROR function takes
- two_arg_same(1, 1, 1); //~ ERROR this function takes
- two_arg_same(1, 1, 1.0); //~ ERROR this function takes
+ two_arg_same(1, 1, 1); //~ ERROR function takes
+ two_arg_same(1, 1, 1.0); //~ ERROR function takes
- two_arg_diff(1, 1, ""); //~ ERROR this function takes
- two_arg_diff(1, "", ""); //~ ERROR this function takes
- two_arg_diff(1, 1, "", ""); //~ ERROR this function takes
- two_arg_diff(1, "", 1, ""); //~ ERROR this function takes
+ two_arg_diff(1, 1, ""); //~ ERROR function takes
+ two_arg_diff(1, "", ""); //~ ERROR function takes
+ two_arg_diff(1, 1, "", ""); //~ ERROR function takes
+ two_arg_diff(1, "", 1, ""); //~ ERROR function takes
// Check with weird spacing and newlines
- two_arg_same(1, 1, ""); //~ ERROR this function takes
- two_arg_diff(1, 1, ""); //~ ERROR this function takes
- two_arg_same( //~ ERROR this function takes
+ two_arg_same(1, 1, ""); //~ ERROR function takes
+ two_arg_diff(1, 1, ""); //~ ERROR function takes
+ two_arg_same( //~ ERROR function takes
1,
1,
""
);
- two_arg_diff( //~ ERROR this function takes
+ two_arg_diff( //~ ERROR function takes
1,
1,
""
fn main() {
foo::<()>(());
- //~^ ERROR this function takes 0 generic arguments but 1 generic argument was supplied
+ //~^ ERROR function takes 0 generic arguments but 1 generic argument was supplied
//~| ERROR `()` doesn't implement `std::fmt::Display`
}
fn four_shuffle(_a: T1, _b: T2, _c: T3, _d: T4) {}
fn main() {
- three_diff(T2::new(0)); //~ ERROR this function takes
+ three_diff(T2::new(0)); //~ ERROR function takes
four_shuffle(T3::default(), T4::default(), T1::default(), T2::default()); //~ ERROR 35:5: 35:17: arguments to this function are incorrect [E0308]
four_shuffle(T3::default(), T2::default(), T1::default(), T3::default()); //~ ERROR 36:5: 36:17: arguments to this function are incorrect [E0308]
) {}
fn main() {
- f(C, A, A, A, B, B, C); //~ ERROR this function takes 6 arguments but 7 arguments were supplied [E0061]
+ f(C, A, A, A, B, B, C); //~ ERROR function takes 6 arguments but 7 arguments were supplied [E0061]
f(C, C, A, A, B, B); //~ ERROR arguments to this function are incorrect [E0308]
f(A, A, D, D, B, B); //~ arguments to this function are incorrect [E0308]
f(C, C, B, B, A, A); //~ arguments to this function are incorrect [E0308]
fn main() {
let x = arg(); // `x` must be inferred
// The reference on `&x` is important to reproduce the ICE
- f(&x, ""); //~ ERROR this function takes 3 arguments but 2 arguments were supplied
+ f(&x, ""); //~ ERROR function takes 3 arguments but 2 arguments were supplied
}
fn main() {
g((), ());
- //~^ ERROR this function takes 6 arguments but 2 arguments were supplied
+ //~^ ERROR function takes 6 arguments but 2 arguments were supplied
}
pub fn g(a1: (), a2: bool, a3: bool, a4: bool, a5: bool, a6: ()) -> () {}
fn main() {
foo(&&A, B, C, D, E, F, G);
- //~^ ERROR this function takes 4 arguments but 7 arguments were supplied
+ //~^ ERROR function takes 4 arguments but 7 arguments were supplied
}
fn main() {
(|_, ()| ())(if true {} else {return;});
- //~^ ERROR this function takes 2 arguments but 1 argument was supplied
+ //~^ ERROR function takes 2 arguments but 1 argument was supplied
}
fn main() {
(|_, ()| ())([return, ()]);
- //~^ ERROR this function takes 2 arguments but 1 argument was supplied
+ //~^ ERROR function takes 2 arguments but 1 argument was supplied
}
fn main() {
let f = |_: (), f: fn()| f;
let _f = f(main);
- //~^ ERROR this function takes 2 arguments but 1 argument was supplied
+ //~^ ERROR function takes 2 arguments but 1 argument was supplied
}
fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {}
fn main() {
- one_arg(); //~ ERROR this function takes
+ one_arg(); //~ ERROR function takes
// The headers here show the types expected,
// with formatting to emphasize which arguments are missing
/* i32 f32 */
- two_same( ); //~ ERROR this function takes
- two_same( 1 ); //~ ERROR this function takes
- two_diff( ); //~ ERROR this function takes
- two_diff( 1 ); //~ ERROR this function takes
- two_diff( 1.0 ); //~ ERROR this function takes
+ two_same( ); //~ ERROR function takes
+ two_same( 1 ); //~ ERROR function takes
+ two_diff( ); //~ ERROR function takes
+ two_diff( 1 ); //~ ERROR function takes
+ two_diff( 1.0 ); //~ ERROR function takes
/* i32 i32 i32 */
- three_same( ); //~ ERROR this function takes
- three_same( 1 ); //~ ERROR this function takes
- three_same( 1, 1 ); //~ ERROR this function takes
+ three_same( ); //~ ERROR function takes
+ three_same( 1 ); //~ ERROR function takes
+ three_same( 1, 1 ); //~ ERROR function takes
/* i32 f32 &str */
- three_diff( 1.0, "" ); //~ ERROR this function takes
- three_diff( 1, "" ); //~ ERROR this function takes
- three_diff( 1, 1.0 ); //~ ERROR this function takes
- three_diff( "" ); //~ ERROR this function takes
- three_diff( 1.0 ); //~ ERROR this function takes
- three_diff( 1 ); //~ ERROR this function takes
+ three_diff( 1.0, "" ); //~ ERROR function takes
+ three_diff( 1, "" ); //~ ERROR function takes
+ three_diff( 1, 1.0 ); //~ ERROR function takes
+ three_diff( "" ); //~ ERROR function takes
+ three_diff( 1.0 ); //~ ERROR function takes
+ three_diff( 1 ); //~ ERROR function takes
/* i32 f32 f32 &str */
- four_repeated( ); //~ ERROR this function takes
- four_repeated( 1, "" ); //~ ERROR this function takes
+ four_repeated( ); //~ ERROR function takes
+ four_repeated( 1, "" ); //~ ERROR function takes
/* i32 f32 i32 f32 &str */
- complex( ); //~ ERROR this function takes
- complex( 1, "" ); //~ ERROR this function takes
+ complex( ); //~ ERROR function takes
+ complex( 1, "" ); //~ ERROR function takes
}
fn main() {
// Extra + Invalid
- two_args(1, "", X {}); //~ ERROR this function takes
- three_args(1, "", X {}, ""); //~ ERROR this function takes
+ two_args(1, "", X {}); //~ ERROR function takes
+ three_args(1, "", X {}, ""); //~ ERROR function takes
// Missing and Invalid
- three_args(1, X {}); //~ ERROR this function takes
+ three_args(1, X {}); //~ ERROR function takes
// Missing and Extra
three_args(1, "", X {}); //~ ERROR arguments to this function are incorrect
three_args("", X {}, 1); //~ ERROR arguments to this function are incorrect
// Swapped and missing
- three_args("", 1); //~ ERROR this function takes
+ three_args("", 1); //~ ERROR function takes
}
LL | qux.foo(a, b, c, d, e, f, g, h, i, j, k, l);
| --- ^ expected `i32`, found `&i32`
| |
- | arguments to this function are incorrect
+ | arguments to this method are incorrect
|
note: associated function defined here
--> $DIR/too-long.rs:4:8
--- /dev/null
+pub trait TraitWAssocConst {
+ const A: usize;
+}
+pub struct Demo {}
+
+impl TraitWAssocConst for impl Demo { //~ ERROR E0404
+ //~^ ERROR E0562
+ pubconst A: str = 32; //~ ERROR expected one of
+}
+
+fn foo<A: TraitWAssocConst<A=32>>() { //~ ERROR E0658
+ foo::<Demo>()(); //~ ERROR E0271
+ //~^ ERROR E0618
+ //~| ERROR E0277
+}
+
+fn main<A: TraitWAssocConst<A=32>>() { //~ ERROR E0131
+ //~^ ERROR E0658
+ foo::<Demo>(); //~ ERROR E0277
+ //~^ ERROR E0271
+}
--- /dev/null
+error: expected one of `!` or `::`, found `A`
+ --> $DIR/issue-105330.rs:8:14
+ |
+LL | impl TraitWAssocConst for impl Demo {
+ | - while parsing this item list starting here
+LL |
+LL | pubconst A: str = 32;
+ | ^ expected one of `!` or `::`
+LL | }
+ | - the item list ends here
+
+error[E0404]: expected trait, found struct `Demo`
+ --> $DIR/issue-105330.rs:6:32
+ |
+LL | impl TraitWAssocConst for impl Demo {
+ | ^^^^ not a trait
+
+error[E0658]: associated const equality is incomplete
+ --> $DIR/issue-105330.rs:11:28
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^
+ |
+ = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
+ = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+
+error[E0658]: associated const equality is incomplete
+ --> $DIR/issue-105330.rs:17:29
+ |
+LL | fn main<A: TraitWAssocConst<A=32>>() {
+ | ^^^^
+ |
+ = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
+ = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
+ --> $DIR/issue-105330.rs:6:27
+ |
+LL | impl TraitWAssocConst for impl Demo {
+ | ^^^^^^^^^
+
+error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
+ --> $DIR/issue-105330.rs:12:11
+ |
+LL | foo::<Demo>()();
+ | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
+ |
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:11
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
+ --> $DIR/issue-105330.rs:12:11
+ |
+LL | foo::<Demo>()();
+ | ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
+ |
+ = note: expected constant `32`
+ found constant `<Demo as TraitWAssocConst>::A`
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:28
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^ required by this bound in `foo`
+
+error[E0618]: expected function, found `()`
+ --> $DIR/issue-105330.rs:12:5
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ----------------------------------- `foo::<Demo>` defined here returns `()`
+LL | foo::<Demo>()();
+ | ^^^^^^^^^^^^^--
+ | |
+ | call expression requires function
+
+error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
+ --> $DIR/issue-105330.rs:19:11
+ |
+LL | foo::<Demo>();
+ | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
+ |
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:11
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
+ --> $DIR/issue-105330.rs:19:11
+ |
+LL | foo::<Demo>();
+ | ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
+ |
+ = note: expected constant `32`
+ found constant `<Demo as TraitWAssocConst>::A`
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:28
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^ required by this bound in `foo`
+
+error[E0131]: `main` function is not allowed to have generic parameters
+ --> $DIR/issue-105330.rs:17:8
+ |
+LL | fn main<A: TraitWAssocConst<A=32>>() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters
+
+error: aborting due to 11 previous errors
+
+Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658.
+For more information about an error, try `rustc --explain E0131`.
LL | fn f() { ModelT.chip_paint(Blue); }
| ---------- ^^^^ expected struct `Black`, found struct `Blue`
| |
- | arguments to this function are incorrect
+ | arguments to this method are incorrect
|
note: associated function defined here
--> $DIR/associated-type-projection-from-supertrait.rs:12:8
LL | fn g() { ModelU.chip_paint(Black); }
| ---------- ^^^^^ expected struct `Blue`, found struct `Black`
| |
- | arguments to this function are incorrect
+ | arguments to this method are incorrect
|
note: associated function defined here
--> $DIR/associated-type-projection-from-supertrait.rs:12:8
--- /dev/null
+// run-pass
+struct S<T: 'static>(#[allow(unused_tuple_struct_fields)] Option<&'static T>);
+
+trait Tr { type Out; }
+impl<T> Tr for T { type Out = T; }
+
+impl<T: 'static> Copy for S<T> where S<T>: Tr<Out=T> {}
+impl<T: 'static> Clone for S<T> where S<T>: Tr<Out=T> {
+ fn clone(&self) -> Self { *self }
+}
+fn main() {
+ S::<()>(None);
+}
--- /dev/null
+// run-pass
+pub trait Parser {
+ type Input;
+}
+
+pub struct Iter<P: Parser>(#[allow(unused_tuple_struct_fields)] P, P::Input);
+
+#[allow(unused_tuple_struct_fields)]
+pub struct Map<P, F>(P, F);
+impl<P, F> Parser for Map<P, F> where F: FnMut(P) {
+ type Input = u8;
+}
+
+trait AstId { type Untyped; }
+impl AstId for u32 { type Untyped = u32; }
+
+fn record_type<Id: AstId>(i: Id::Untyped) -> u8 {
+ Iter(Map(i, |_: Id::Untyped| {}), 42).1
+}
+
+pub fn main() {
+ assert_eq!(record_type::<u32>(3), 42);
+}
--- /dev/null
+struct S<T: 'static>(#[allow(unused_tuple_struct_fields)] Option<&'static T>);
+
+trait Tr { type Out; }
+impl<T> Tr for T { type Out = T; }
+
+impl<T: 'static> Copy for S<T> where S<T>: Tr<Out=T> {}
+impl<T: 'static> Clone for S<T> where S<T>: Tr<Out=T> {
+ fn clone(&self) -> Self { *self }
+}
+fn main() {
+ let t = S::<()>(None);
+ drop(t);
+ drop(t); //~ ERROR use of moved value
+}
--- /dev/null
+error[E0382]: use of moved value: `t`
+ --> $DIR/issue-25700.rs:13:10
+ |
+LL | let t = S::<()>(None);
+ | - move occurs because `t` has type `S<()>`, which does not implement the `Copy` trait
+LL | drop(t);
+ | - value moved here
+LL | drop(t);
+ | ^ value used here after move
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
fn main() {
unsafe {
- foo(); //~ ERROR this function takes at least 2 arguments but 0 arguments were supplied
- foo(1); //~ ERROR this function takes at least 2 arguments but 1 argument was supplied
+ foo(); //~ ERROR function takes at least 2 arguments but 0 arguments were supplied
+ foo(1); //~ ERROR function takes at least 2 arguments but 1 argument was supplied
let x: unsafe extern "C" fn(f: isize, x: u8) = foo; //~ ERROR mismatched types
let y: extern "C" fn(f: isize, x: u8, ...) = bar; //~ ERROR mismatched types
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
fn main() {
1 + 2;
// run-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
fn main() {
assert_eq!(1, 1);
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo {}
// check-fail
// known-bug: unknown
-// compile-flags: -Z chalk --edition=2021
+// compile-flags: -Z trait-solver=chalk --edition=2021
fn main() -> () {}
// run-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
// Test that `Clone` is correctly implemented for builtin types.
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo { }
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
fn main() -> () {
let t = || {};
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo { }
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo: Sized { }
// Split out of impl_wf.rs to work around rust aborting compilation early
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo: Sized { }
// run-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo { }
// run-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo { }
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
#![allow(dead_code)]
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
#![allow(dead_code)]
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
#![allow(dead_code)]
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo { }
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
struct Foo<'a, T> where Box<T>: Clone {
_x: std::marker::PhantomData<&'a T>,
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Bar { }
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo<F: ?Sized> where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8
{
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
use std::borrow::Borrow;
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
fn main() {
println!("hello");
// run-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo { }
// FIXME(chalk): should fail, see comments
// check-fail
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
#![feature(trivial_bounds)]
// run-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo { }
trait Bar: Foo { }
// check-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
use std::fmt::Display;
// run-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo { }
trait Bar<U> where U: Foo { }
// run-pass
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Eq { }
trait Hash: Eq { }
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo { }
impl Foo for i32 { }
// check-fail
-// compile-flags: -Z chalk
+// compile-flags: -Z trait-solver=chalk
trait Foo { }
--- /dev/null
+// check-pass
+
+trait Foo<'a> {
+ type Input;
+}
+
+impl<F: Fn(u32)> Foo<'_> for F {
+ type Input = u32;
+}
+
+trait SuperFn: for<'a> Foo<'a> + for<'a> Fn(<Self as Foo<'a>>::Input) {}
+impl<T> SuperFn for T where T: for<'a> Fn(<Self as Foo<'a>>::Input) + for<'a> Foo<'a> {}
+
+fn needs_super(_: impl SuperFn) {}
+
+fn main() {
+ needs_super(|_: u32| {});
+}
--- /dev/null
+// check-pass
+
+
+trait Foo<'a> {
+ type Input;
+}
+
+impl<F: Fn(u32)> Foo<'_> for F {
+ type Input = u32;
+}
+
+fn needs_super<F: for<'a> Fn(<F as Foo<'a>>::Input) + for<'a> Foo<'a>>(_: F) {}
+
+fn main() {
+ needs_super(|_: u32| {});
+}
--- /dev/null
+// edition:2021
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![feature(closure_lifetime_binder)]
+
+use std::future::Future;
+
+trait AsyncFn<I, R>: FnMut(I) -> Self::Fut {
+ type Fut: Future<Output = R>;
+}
+
+impl<F, I, R, Fut> AsyncFn<I, R> for F
+where
+ Fut: Future<Output = R>,
+ F: FnMut(I) -> Fut,
+{
+ type Fut = Fut;
+}
+
+async fn call<C, R, F>(mut ctx: C, mut f: F) -> Result<R, ()>
+where
+ F: for<'a> AsyncFn<&'a mut C, Result<R, ()>>,
+{
+ loop {
+ match f(&mut ctx).await {
+ Ok(val) => return Ok(val),
+ Err(_) => continue,
+ }
+ }
+}
+
+trait Cap<'a> {}
+impl<T> Cap<'_> for T {}
+
+fn works(ctx: &mut usize) {
+ let mut inner = 0;
+
+ type Ret<'a, 'b: 'a> = impl Future<Output = Result<usize, ()>> + 'a + Cap<'b>;
+
+ let callback = for<'a, 'b> |c: &'a mut &'b mut usize| -> Ret<'a, 'b> {
+ inner += 1;
+ async move {
+ let _c = c;
+ Ok(1usize)
+ }
+ };
+ call(ctx, callback);
+}
+
+fn doesnt_work_but_should(ctx: &mut usize) {
+ let mut inner = 0;
+
+ type Ret<'a, 'b: 'a> = impl Future<Output = Result<usize, ()>> + 'a + Cap<'b>;
+
+ call(ctx, for<'a, 'b> |c: &'a mut &'b mut usize| -> Ret<'a, 'b> {
+ inner += 1;
+ async move {
+ let _c = c;
+ Ok(1usize)
+ }
+ });
+}
+
+fn main() {}
--- /dev/null
+// run-pass
+// compile-flags: -Copt-level=0 -Cdebuginfo=2
+
+// Make sure LLVM does not miscompile this.
+
+fn indirect_get_slice() -> &'static [usize] {
+ &[]
+}
+
+#[inline(always)]
+fn get_slice() -> &'static [usize] {
+ let ret = indirect_get_slice();
+ ret
+}
+
+fn main() {
+ let output = get_slice().len();
+ assert_eq!(output, 0);
+}
--- /dev/null
+// run-pass
+// ignore-emscripten no processes
+// ignore-sgx no processes
+
+// Make sure that if a process doesn't have its stdio/stderr descriptors set up
+// that we don't die in a large ball of fire
+
+use std::env;
+use std::process::{Command, Stdio};
+
+pub fn main () {
+ let args: Vec<String> = env::args().collect();
+ if args.len() > 1 && args[1] == "child" {
+ for _ in 0..1000 {
+ println!("hello?");
+ }
+ for _ in 0..1000 {
+ println!("hello?");
+ }
+ return;
+ }
+
+ let mut p = Command::new(&args[0]);
+ p.arg("child").stdout(Stdio::null()).stderr(Stdio::null());
+ println!("{:?}", p.spawn().unwrap().wait());
+}
fn main() {
test::<2>();
- //~^ ERROR this function takes 2 generic arguments
+ //~^ ERROR function takes 2 generic arguments
}
fn main() {
foo::<0>();
- //~^ ERROR this function takes 2
+ //~^ ERROR function takes 2
foo::<0, 0, 0>();
- //~^ ERROR this function takes 2
+ //~^ ERROR function takes 2
}
--- /dev/null
+// run-pass
+#![allow(dead_code)]
+#![allow(non_camel_case_types)]
+
+// pretty-expanded FIXME #23616
+
+trait hax {
+ fn dummy(&self) { }
+}
+impl<A> hax for A { }
+
+fn perform_hax<T: 'static>(x: Box<T>) -> Box<dyn hax+'static> {
+ Box::new(x) as Box<dyn hax+'static>
+}
+
+fn deadcode() {
+ perform_hax(Box::new("deadcode".to_string()));
+}
+
+pub fn main() {
+ let _ = perform_hax(Box::new(42));
+}
--- /dev/null
+// run-pass
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
+
+struct A(i32);
+
+impl Drop for A {
+ fn drop(&mut self) {
+ // update global drop count
+ DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
+ }
+}
+
+static FOO: A = A(123);
+const BAR: A = A(456);
+
+impl A {
+ const BAZ: A = A(789);
+}
+
+fn main() {
+ assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0);
+ assert_eq!(&FOO.0, &123);
+ assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0);
+ assert_eq!(BAR.0, 456);
+ assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 1);
+ assert_eq!(A::BAZ.0, 789);
+ assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
+}
--- /dev/null
+use std::collections::BTreeSet;
+
+#[derive(Hash)]
+pub enum ElemDerived {
+ //~^ ERROR recursive type `ElemDerived` has infinite size
+ A(ElemDerived)
+}
+
+
+pub enum Elem {
+ Derived(ElemDerived)
+}
+
+pub struct Set(BTreeSet<Elem>);
+
+impl Set {
+ pub fn into_iter(self) -> impl Iterator<Item = Elem> {
+ self.0.into_iter()
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0072]: recursive type `ElemDerived` has infinite size
+ --> $DIR/issue-72554.rs:4:1
+ |
+LL | pub enum ElemDerived {
+ | ^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | A(ElemDerived)
+ | ----------- recursive without indirection
+ |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
+ |
+LL | A(Box<ElemDerived>)
+ | ++++ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0072`.
--- /dev/null
+// run-pass
+#![feature(fn_traits, unboxed_closures)]
+use std::ops::Fn;
+
+struct Foo<T>(T);
+
+impl<T: Copy> Fn<()> for Foo<T> {
+ extern "rust-call" fn call(&self, _: ()) -> T {
+ match *self {
+ Foo(t) => t
+ }
+ }
+}
+
+impl<T: Copy> FnMut<()> for Foo<T> {
+ extern "rust-call" fn call_mut(&mut self, _: ()) -> T {
+ self.call(())
+ }
+}
+
+impl<T: Copy> FnOnce<()> for Foo<T> {
+ type Output = T;
+
+ extern "rust-call" fn call_once(self, _: ()) -> T {
+ self.call(())
+ }
+}
+
+fn main() {
+ let t: u8 = 1;
+ println!("{}", Foo(t)());
+}
fn main() {
let needlesArr: Vec<char> = vec!['a', 'f'];
needlesArr.iter().fold(|x, y| {
- //~^ ERROR this function takes 2 arguments but 1 argument was supplied
+ //~^ ERROR this method takes 2 arguments but 1 argument was supplied
});
}
-error[E0061]: this function takes 2 arguments but 1 argument was supplied
+error[E0061]: this method takes 2 arguments but 1 argument was supplied
--> $DIR/issue-3044.rs:3:23
|
LL | needlesArr.iter().fold(|x, y| {
a = d;
};
Pin::new(&mut b).resume();
- //~^ ERROR this function takes 1 argument but 0 arguments were supplied
+ //~^ ERROR this method takes 1 argument but 0 arguments were supplied
// This type error is required to reproduce the ICE...
}
-error[E0061]: this function takes 1 argument but 0 arguments were supplied
+error[E0061]: this method takes 1 argument but 0 arguments were supplied
--> $DIR/issue-102645.rs:16:22
|
LL | Pin::new(&mut b).resume();
{}
fn main() {
- f(&[f()]); //~ ERROR this function takes 1 argument
+ f(&[f()]); //~ ERROR function takes 1 argument
}
fn main() {
f::<[u8]>("a", b"a");
- //~^ ERROR: this function takes 2 generic arguments but 1 generic argument was supplied
+ //~^ ERROR function takes 2 generic arguments but 1 generic argument was supplied
}
--- /dev/null
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete
+
+struct TestA {}
+struct TestB {}
+
+impl TestTrait for TestA {
+ type Output = ();
+}
+impl TestTrait for TestB {
+ type Output = ();
+}
+
+trait TestTrait {
+ type Output;
+}
+
+impl<A, B> TestTrait for GreeterOutput<A, B>
+where
+ A: TestTrait<Output = ()>,
+ B: TestTrait<Output = ()>,
+{
+ type Output = ();
+}
+
+enum GreeterOutput<A, B>
+where
+ A: TestTrait<Output = ()>,
+ B: TestTrait<Output = ()>,
+{
+ SayHello(A),
+ SayGoodbye(B),
+}
+
+trait Greeter {
+ fn test_func(&self, func: &str) -> impl TestTrait<Output = ()> {
+ match func {
+ "SayHello" => GreeterOutput::SayHello(TestA {}),
+ "SayGoodbye" => GreeterOutput::SayGoodbye(TestB {}),
+ _ => GreeterOutput::SayHello(TestA {}),
+ }
+ }
+}
+
+fn main() {
+ println!("Hello, world!");
+}
--- /dev/null
+warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/box-coerce-span-in-default.rs:3:12
+ |
+LL | #![feature(return_position_impl_trait_in_trait)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
// A test exploiting the bug behind #25860 except with
-// implied trait bounds which currently don't exist without `-Zchalk`.
+// implied trait bounds which currently don't exist without `-Ztrait-solver=chalk`.
use std::marker::PhantomData;
struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>)
where
+++ /dev/null
-pub trait TraitWAssocConst {
- const A: usize;
-}
-pub struct Demo {}
-
-impl TraitWAssocConst for impl Demo { //~ ERROR E0404
- //~^ ERROR E0562
- pubconst A: str = 32; //~ ERROR expected one of
-}
-
-fn foo<A: TraitWAssocConst<A=32>>() { //~ ERROR E0658
- foo::<Demo>()(); //~ ERROR E0271
- //~^ ERROR E0618
- //~| ERROR E0277
-}
-
-fn main<A: TraitWAssocConst<A=32>>() { //~ ERROR E0131
- //~^ ERROR E0658
- foo::<Demo>(); //~ ERROR E0277
- //~^ ERROR E0271
-}
+++ /dev/null
-error: expected one of `!` or `::`, found `A`
- --> $DIR/issue-105330.rs:8:14
- |
-LL | impl TraitWAssocConst for impl Demo {
- | - while parsing this item list starting here
-LL |
-LL | pubconst A: str = 32;
- | ^ expected one of `!` or `::`
-LL | }
- | - the item list ends here
-
-error[E0404]: expected trait, found struct `Demo`
- --> $DIR/issue-105330.rs:6:32
- |
-LL | impl TraitWAssocConst for impl Demo {
- | ^^^^ not a trait
-
-error[E0658]: associated const equality is incomplete
- --> $DIR/issue-105330.rs:11:28
- |
-LL | fn foo<A: TraitWAssocConst<A=32>>() {
- | ^^^^
- |
- = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
- = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
-
-error[E0658]: associated const equality is incomplete
- --> $DIR/issue-105330.rs:17:29
- |
-LL | fn main<A: TraitWAssocConst<A=32>>() {
- | ^^^^
- |
- = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
- = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
-
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/issue-105330.rs:6:27
- |
-LL | impl TraitWAssocConst for impl Demo {
- | ^^^^^^^^^
-
-error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
- --> $DIR/issue-105330.rs:12:11
- |
-LL | foo::<Demo>()();
- | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
- |
-note: required by a bound in `foo`
- --> $DIR/issue-105330.rs:11:11
- |
-LL | fn foo<A: TraitWAssocConst<A=32>>() {
- | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
-
-error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
- --> $DIR/issue-105330.rs:12:11
- |
-LL | foo::<Demo>()();
- | ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
- |
- = note: expected constant `32`
- found constant `<Demo as TraitWAssocConst>::A`
-note: required by a bound in `foo`
- --> $DIR/issue-105330.rs:11:28
- |
-LL | fn foo<A: TraitWAssocConst<A=32>>() {
- | ^^^^ required by this bound in `foo`
-
-error[E0618]: expected function, found `()`
- --> $DIR/issue-105330.rs:12:5
- |
-LL | fn foo<A: TraitWAssocConst<A=32>>() {
- | ----------------------------------- `foo::<Demo>` defined here returns `()`
-LL | foo::<Demo>()();
- | ^^^^^^^^^^^^^--
- | |
- | call expression requires function
-
-error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
- --> $DIR/issue-105330.rs:19:11
- |
-LL | foo::<Demo>();
- | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
- |
-note: required by a bound in `foo`
- --> $DIR/issue-105330.rs:11:11
- |
-LL | fn foo<A: TraitWAssocConst<A=32>>() {
- | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
-
-error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
- --> $DIR/issue-105330.rs:19:11
- |
-LL | foo::<Demo>();
- | ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
- |
- = note: expected constant `32`
- found constant `<Demo as TraitWAssocConst>::A`
-note: required by a bound in `foo`
- --> $DIR/issue-105330.rs:11:28
- |
-LL | fn foo<A: TraitWAssocConst<A=32>>() {
- | ^^^^ required by this bound in `foo`
-
-error[E0131]: `main` function is not allowed to have generic parameters
- --> $DIR/issue-105330.rs:17:8
- |
-LL | fn main<A: TraitWAssocConst<A=32>>() {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters
-
-error: aborting due to 11 previous errors
-
-Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658.
-For more information about an error, try `rustc --explain E0131`.
+++ /dev/null
-// We only want to assert that this doesn't ICE, we don't particularly care
-// about whether it nor it fails to compile.
-
-macro_rules! foo{
- () => {{
- macro_rules! bar{() => (())}
- 1
- }}
-}
-
-pub fn main() {
- foo!();
-
- assert!({one! two()}); //~ ERROR expected one of `(`, `[`, or `{`, found `two`
-
- // regardless of whether nested macro_rules works, the following should at
- // least throw a conventional error.
- assert!({one! two}); //~ ERROR expected one of `(`, `[`, or `{`, found `two`
-}
+++ /dev/null
-error: expected one of `(`, `[`, or `{`, found `two`
- --> $DIR/issue-10536.rs:14:19
- |
-LL | assert!({one! two()});
- | ^^^ expected one of `(`, `[`, or `{`
-
-error: expected one of `(`, `[`, or `{`, found `two`
- --> $DIR/issue-10536.rs:18:19
- |
-LL | assert!({one! two});
- | ^^^ expected one of `(`, `[`, or `{`
-
-error: aborting due to 2 previous errors
-
+++ /dev/null
-// run-pass
-// ignore-emscripten no processes
-// ignore-sgx no processes
-
-// Make sure that if a process doesn't have its stdio/stderr descriptors set up
-// that we don't die in a large ball of fire
-
-use std::env;
-use std::process::{Command, Stdio};
-
-pub fn main () {
- let args: Vec<String> = env::args().collect();
- if args.len() > 1 && args[1] == "child" {
- for _ in 0..1000 {
- println!("hello?");
- }
- for _ in 0..1000 {
- println!("hello?");
- }
- return;
- }
-
- let mut p = Command::new(&args[0]);
- p.arg("child").stdout(Stdio::null()).stderr(Stdio::null());
- println!("{:?}", p.spawn().unwrap().wait());
-}
| | |
| | expected `&mut [u8]`, found struct `Vec`
| | help: consider mutably borrowing here: `&mut v`
- | arguments to this function are incorrect
+ | arguments to this method are incorrect
|
= note: expected mutable reference `&mut [u8]`
found struct `Vec<_>`
+++ /dev/null
-// run-pass
-#![feature(fn_traits, unboxed_closures)]
-use std::ops::Fn;
-
-struct Foo<T>(T);
-
-impl<T: Copy> Fn<()> for Foo<T> {
- extern "rust-call" fn call(&self, _: ()) -> T {
- match *self {
- Foo(t) => t
- }
- }
-}
-
-impl<T: Copy> FnMut<()> for Foo<T> {
- extern "rust-call" fn call_mut(&mut self, _: ()) -> T {
- self.call(())
- }
-}
-
-impl<T: Copy> FnOnce<()> for Foo<T> {
- type Output = T;
-
- extern "rust-call" fn call_once(self, _: ()) -> T {
- self.call(())
- }
-}
-
-fn main() {
- let t: u8 = 1;
- println!("{}", Foo(t)());
-}
+++ /dev/null
-// run-pass
-// Test that we are able to type-check this example. In particular,
-// knowing that `T: 'a` allows us to deduce that `[U]: 'a` (because
-// when `T=[U]` it implies that `U: 'a`).
-//
-// Regr. test for live code we found in the wild when fixing #18937.
-
-pub trait Leak<T : ?Sized> {
- fn leak<'a>(self) -> &'a T where T: 'a;
-}
-
-impl<U> Leak<[U]> for Vec<U> {
- fn leak<'a>(mut self) -> &'a [U] where [U]: 'a {
- let r: *mut [U] = &mut self[..];
- std::mem::forget(self);
- unsafe { &mut *r }
- }
-}
-fn main() {
- println!("Hello, world!");
-}
+++ /dev/null
-// Regression test for #18937.
-
-use std::fmt;
-
-#[derive(Debug)]
-struct MyString<'a>(&'a String);
-
-struct B {
- list: Vec<Box<dyn fmt::Debug>>,
-}
-
-trait A<'a> {
- fn foo<F>(&mut self, f: F)
- where F: fmt::Debug + 'a,
- Self: Sized;
-}
-
-impl<'a> A<'a> for B {
- fn foo<F>(&mut self, f: F)
- where F: fmt::Debug + 'static, //~ ERROR impl has stricter
- {
- self.list.push(Box::new(f));
- }
-}
-
-fn main() {
- let mut b = B { list: Vec::new() };
-
- // Create a borrowed pointer, put it in `b`, then drop what's borrowing it
- let a = "hello".to_string();
- b.foo(MyString(&a));
-
- // Drop the data which `b` has a reference to
- drop(a);
-
- // Use the data, probably segfaulting
- for b in b.list.iter() {
- println!("{:?}", b);
- }
-}
+++ /dev/null
-error[E0276]: impl has stricter requirements than trait
- --> $DIR/issue-18937.rs:20:31
- |
-LL | / fn foo<F>(&mut self, f: F)
-LL | | where F: fmt::Debug + 'a,
-LL | | Self: Sized;
- | |__________________________- definition of `foo` from trait
-...
-LL | where F: fmt::Debug + 'static,
- | ^^^^^^^ impl has extra requirement `F: 'static`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0276`.
--> $DIR/issue-25439.rs:8:9
|
LL | fix(|_, x| x);
- | ^^^^^^^^ cyclic type of infinite size
+ | ^^^^^^ cyclic type of infinite size
|
= note: closures cannot capture themselves or take themselves as argument;
this error may be the result of a recent compiler bug-fix,
see issue #46062 <https://github.com/rust-lang/rust/issues/46062>
for more information
+note: required by a bound in `fix`
+ --> $DIR/issue-25439.rs:3:33
+ |
+LL | fn fix<F>(f: F) -> i32 where F: Fn(Helper<F>, i32) -> i32 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `fix`
error: aborting due to previous error
+++ /dev/null
-// run-pass
-struct S<T: 'static>(#[allow(unused_tuple_struct_fields)] Option<&'static T>);
-
-trait Tr { type Out; }
-impl<T> Tr for T { type Out = T; }
-
-impl<T: 'static> Copy for S<T> where S<T>: Tr<Out=T> {}
-impl<T: 'static> Clone for S<T> where S<T>: Tr<Out=T> {
- fn clone(&self) -> Self { *self }
-}
-fn main() {
- S::<()>(None);
-}
+++ /dev/null
-// run-pass
-pub trait Parser {
- type Input;
-}
-
-pub struct Iter<P: Parser>(#[allow(unused_tuple_struct_fields)] P, P::Input);
-
-#[allow(unused_tuple_struct_fields)]
-pub struct Map<P, F>(P, F);
-impl<P, F> Parser for Map<P, F> where F: FnMut(P) {
- type Input = u8;
-}
-
-trait AstId { type Untyped; }
-impl AstId for u32 { type Untyped = u32; }
-
-fn record_type<Id: AstId>(i: Id::Untyped) -> u8 {
- Iter(Map(i, |_: Id::Untyped| {}), 42).1
-}
-
-pub fn main() {
- assert_eq!(record_type::<u32>(3), 42);
-}
+++ /dev/null
-struct S<T: 'static>(#[allow(unused_tuple_struct_fields)] Option<&'static T>);
-
-trait Tr { type Out; }
-impl<T> Tr for T { type Out = T; }
-
-impl<T: 'static> Copy for S<T> where S<T>: Tr<Out=T> {}
-impl<T: 'static> Clone for S<T> where S<T>: Tr<Out=T> {
- fn clone(&self) -> Self { *self }
-}
-fn main() {
- let t = S::<()>(None);
- drop(t);
- drop(t); //~ ERROR use of moved value
-}
+++ /dev/null
-error[E0382]: use of moved value: `t`
- --> $DIR/issue-25700.rs:13:10
- |
-LL | let t = S::<()>(None);
- | - move occurs because `t` has type `S<()>`, which does not implement the `Copy` trait
-LL | drop(t);
- | - value moved here
-LL | drop(t);
- | ^ value used here after move
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0382`.
fn main() {
some_macro!(some_function);
- //~^ ERROR this function takes 0 arguments but 1 argument was supplied
+ //~^ ERROR function takes 0 arguments but 1 argument was supplied
//~| NOTE in this expansion of some_macro!
}
+++ /dev/null
-// run-pass
-#![allow(dead_code)]
-#![allow(non_camel_case_types)]
-
-// pretty-expanded FIXME #23616
-
-trait hax {
- fn dummy(&self) { }
-}
-impl<A> hax for A { }
-
-fn perform_hax<T: 'static>(x: Box<T>) -> Box<dyn hax+'static> {
- Box::new(x) as Box<dyn hax+'static>
-}
-
-fn deadcode() {
- perform_hax(Box::new("deadcode".to_string()));
-}
-
-pub fn main() {
- let _ = perform_hax(Box::new(42));
-}
+++ /dev/null
-use std::vec::IntoIter;
-
-pub fn get_tok(it: &mut IntoIter<u8>) {
- let mut found_e = false;
-
- let temp: Vec<u8> = it
- .take_while(|&x| {
- found_e = true;
- false
- })
- .cloned() //~ ERROR to be an iterator that yields `&_`, but it yields `u8`
- .collect(); //~ ERROR the method
-}
-
-fn main() {}
+++ /dev/null
-error[E0271]: expected `TakeWhile<&mut IntoIter<u8>, [closure@issue-31173.rs:7:21]>` to be an iterator that yields `&_`, but it yields `u8`
- --> $DIR/issue-31173.rs:11:10
- |
-LL | .cloned()
- | ^^^^^^ expected reference, found `u8`
- |
- = note: expected reference `&_`
- found type `u8`
-note: the method call chain might not have had the expected associated types
- --> $DIR/issue-31173.rs:3:20
- |
-LL | pub fn get_tok(it: &mut IntoIter<u8>) {
- | ^^^^^^^^^^^^^^^^^ `Iterator::Item` is `u8` here
-...
-LL | .take_while(|&x| {
- | __________-
-LL | | found_e = true;
-LL | | false
-LL | | })
- | |__________- `Iterator::Item` remains `u8` here
-note: required by a bound in `cloned`
- --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
-
-error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut IntoIter<u8>, [closure@issue-31173.rs:7:21]>>`, but its trait bounds were not satisfied
- --> $DIR/issue-31173.rs:12:10
- |
-LL | .collect();
- | ^^^^^^^ method cannot be called due to unsatisfied trait bounds
- --> $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
- |
- = note: doesn't satisfy `<_ as Iterator>::Item = &_`
- --> $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
- |
- = note: doesn't satisfy `_: Iterator`
- |
- = note: the following trait bounds were not satisfied:
- `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_`
- which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
- `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
- which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0271, E0599.
-For more information about an error, try `rustc --explain E0271`.
+++ /dev/null
-// run-pass
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
-
-struct A(i32);
-
-impl Drop for A {
- fn drop(&mut self) {
- // update global drop count
- DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
- }
-}
-
-static FOO: A = A(123);
-const BAR: A = A(456);
-
-impl A {
- const BAZ: A = A(789);
-}
-
-fn main() {
- assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0);
- assert_eq!(&FOO.0, &123);
- assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0);
- assert_eq!(BAR.0, 456);
- assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 1);
- assert_eq!(A::BAZ.0, 789);
- assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
-}
LL | b"".starts_with(stringify!(foo))
| ----------- ^^^^^^^^^^^^^^^ expected slice `[u8]`, found `str`
| |
- | arguments to this function are incorrect
+ | arguments to this method are incorrect
|
= note: expected reference `&[u8]`
found reference `&'static str`
fn foo(a: usize) {}
//~^ defined here
fn main() { foo(5, 6) }
-//~^ ERROR this function takes 1 argument but 2 arguments were supplied
+//~^ ERROR function takes 1 argument but 2 arguments were supplied
+++ /dev/null
-fn bug() -> impl for <'r> Fn() -> &'r () { || { &() } }
-//~^ ERROR binding for associated type `Output` references lifetime `'r`
-
-fn main() {
- let f = bug();
-}
+++ /dev/null
-error[E0582]: binding for associated type `Output` references lifetime `'r`, which does not appear in the trait input types
- --> $DIR/issue-54189.rs:1:35
- |
-LL | fn bug() -> impl for <'r> Fn() -> &'r () { || { &() } }
- | ^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0582`.
+++ /dev/null
-use std::collections::BTreeSet;
-
-#[derive(Hash)]
-pub enum ElemDerived {
- //~^ ERROR recursive type `ElemDerived` has infinite size
- A(ElemDerived)
-}
-
-
-pub enum Elem {
- Derived(ElemDerived)
-}
-
-pub struct Set(BTreeSet<Elem>);
-
-impl Set {
- pub fn into_iter(self) -> impl Iterator<Item = Elem> {
- self.0.into_iter()
- }
-}
-
-fn main() {}
+++ /dev/null
-error[E0072]: recursive type `ElemDerived` has infinite size
- --> $DIR/issue-72554.rs:4:1
- |
-LL | pub enum ElemDerived {
- | ^^^^^^^^^^^^^^^^^^^^
-LL |
-LL | A(ElemDerived)
- | ----------- recursive without indirection
- |
-help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
- |
-LL | A(Box<ElemDerived>)
- | ++++ +
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0072`.
+++ /dev/null
-// run-pass
-// compile-flags: -Copt-level=0 -Cdebuginfo=2
-
-// Make sure LLVM does not miscompile this.
-
-fn indirect_get_slice() -> &'static [usize] {
- &[]
-}
-
-#[inline(always)]
-fn get_slice() -> &'static [usize] {
- let ret = indirect_get_slice();
- ret
-}
-
-fn main() {
- let output = get_slice().len();
- assert_eq!(output, 0);
-}
+++ /dev/null
-struct Argument;
-struct Return;
-
-fn function(_: Argument) -> Return { todo!() }
-
-trait Trait {}
-impl Trait for fn(Argument) -> Return {}
-
-fn takes(_: impl Trait) {}
-
-fn main() {
- takes(function);
- //~^ ERROR the trait bound
- takes(|_: Argument| -> Return { todo!() });
- //~^ ERROR the trait bound
-}
+++ /dev/null
-error[E0277]: the trait bound `fn(Argument) -> Return {function}: Trait` is not satisfied
- --> $DIR/issue-99875.rs:12:11
- |
-LL | takes(function);
- | ----- ^^^^^^^^ the trait `Trait` is not implemented for fn item `fn(Argument) -> Return {function}`
- | |
- | required by a bound introduced by this call
- |
- = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return`
-note: required by a bound in `takes`
- --> $DIR/issue-99875.rs:9:18
- |
-LL | fn takes(_: impl Trait) {}
- | ^^^^^ required by this bound in `takes`
-
-error[E0277]: the trait bound `[closure@$DIR/issue-99875.rs:14:11: 14:34]: Trait` is not satisfied
- --> $DIR/issue-99875.rs:14:11
- |
-LL | takes(|_: Argument| -> Return { todo!() });
- | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for closure `[closure@$DIR/issue-99875.rs:14:11: 14:34]`
- | |
- | required by a bound introduced by this call
- |
- = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return`
-note: required by a bound in `takes`
- --> $DIR/issue-99875.rs:9:18
- |
-LL | fn takes(_: impl Trait) {}
- | ^^^^^ required by this bound in `takes`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
//~^ ERROR missing lifetime specifier [E0106]
//~| ERROR mismatched types
-//~| ERROR this function takes 1 argument but 0 arguments were supplied
+//~| ERROR function takes 1 argument but 0 arguments were supplied
fn parse_type_3() -> &str { unimplemented!() }
//~^ ERROR missing lifetime specifier [E0106]
--- /dev/null
+// We only want to assert that this doesn't ICE, we don't particularly care
+// about whether it nor it fails to compile.
+
+macro_rules! foo{
+ () => {{
+ macro_rules! bar{() => (())}
+ 1
+ }}
+}
+
+pub fn main() {
+ foo!();
+
+ assert!({one! two()}); //~ ERROR expected one of `(`, `[`, or `{`, found `two`
+
+ // regardless of whether nested macro_rules works, the following should at
+ // least throw a conventional error.
+ assert!({one! two}); //~ ERROR expected one of `(`, `[`, or `{`, found `two`
+}
--- /dev/null
+error: expected one of `(`, `[`, or `{`, found `two`
+ --> $DIR/issue-10536.rs:14:19
+ |
+LL | assert!({one! two()});
+ | ^^^ expected one of `(`, `[`, or `{`
+
+error: expected one of `(`, `[`, or `{`, found `two`
+ --> $DIR/issue-10536.rs:18:19
+ |
+LL | assert!({one! two});
+ | ^^^ expected one of `(`, `[`, or `{`
+
+error: aborting due to 2 previous errors
+
LL | 1.query::<dyn ToString>("")
| --------------------- ^^ expected trait object `dyn ToString`, found `&str`
| |
- | arguments to this function are incorrect
+ | arguments to this method are incorrect
|
= note: expected trait object `dyn ToString`
found reference `&'static str`
fn main() {
let x = Foo;
- x.zero(0) //~ ERROR this function takes 0 arguments but 1 argument was supplied
- .one() //~ ERROR this function takes 1 argument but 0 arguments were supplied
- .two(0); //~ ERROR this function takes 2 arguments but 1 argument was supplied
+ x.zero(0) //~ ERROR this method takes 0 arguments but 1 argument was supplied
+ .one() //~ ERROR this method takes 1 argument but 0 arguments were supplied
+ .two(0); //~ ERROR this method takes 2 arguments but 1 argument was supplied
let y = Foo;
y.zero()
.take() //~ ERROR not an iterator
.one(0);
- y.three::<usize>(); //~ ERROR this function takes 3 arguments but 0 arguments were supplied
+ y.three::<usize>(); //~ ERROR this method takes 3 arguments but 0 arguments were supplied
}
-error[E0061]: this function takes 0 arguments but 1 argument was supplied
+error[E0061]: this method takes 0 arguments but 1 argument was supplied
--> $DIR/method-call-err-msg.rs:13:7
|
LL | x.zero(0)
LL | x.zero()
| ~~
-error[E0061]: this function takes 1 argument but 0 arguments were supplied
+error[E0061]: this method takes 1 argument but 0 arguments were supplied
--> $DIR/method-call-err-msg.rs:14:7
|
LL | .one()
LL | .one(/* isize */)
| ~~~~~~~~~~~~~
-error[E0061]: this function takes 2 arguments but 1 argument was supplied
+error[E0061]: this method takes 2 arguments but 1 argument was supplied
--> $DIR/method-call-err-msg.rs:15:7
|
LL | .two(0);
= note: the following trait defines an item `take`, perhaps you need to implement it:
candidate #1: `Iterator`
-error[E0061]: this function takes 3 arguments but 0 arguments were supplied
+error[E0061]: this method takes 3 arguments but 0 arguments were supplied
--> $DIR/method-call-err-msg.rs:21:7
|
LL | y.three::<usize>();
let ans = s("what");
//~^ ERROR mismatched types
let ans = s();
- //~^ ERROR this function takes 1 argument but 0 arguments were supplied
+ //~^ ERROR function takes 1 argument but 0 arguments were supplied
let ans = s("burma", "shave");
- //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+ //~^ ERROR function takes 1 argument but 2 arguments were supplied
F("");
//~^ ERROR mismatched types
--- /dev/null
+fn bug() -> impl for <'r> Fn() -> &'r () { || { &() } }
+//~^ ERROR binding for associated type `Output` references lifetime `'r`
+
+fn main() {
+ let f = bug();
+}
--- /dev/null
+error[E0582]: binding for associated type `Output` references lifetime `'r`, which does not appear in the trait input types
+ --> $DIR/issue-54189.rs:1:35
+ |
+LL | fn bug() -> impl for <'r> Fn() -> &'r () { || { &() } }
+ | ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0582`.
fn main() {
foo(1, 2, 3);
- //~^ ERROR this function takes 4 arguments but 3
+ //~^ ERROR function takes 4 arguments but 3
bar(1, 2, 3);
- //~^ ERROR this function takes 6 arguments but 3
+ //~^ ERROR function takes 6 arguments but 3
}
// Make sure primitive type fallback doesn't work in value namespace
std::mem::size_of(u16);
//~^ ERROR expected value, found builtin type `u16`
- //~| ERROR this function takes 0 arguments but 1 argument was supplied
+ //~| ERROR function takes 0 arguments but 1 argument was supplied
// Make sure primitive type fallback doesn't work with global paths
let _: ::u8;
fn main() {
foo(Some(42), 2);
- foo(Some(42), 2, ""); //~ ERROR this function takes
+ foo(Some(42), 2, ""); //~ ERROR function takes
bar("", ""); //~ ERROR mismatched types
bar(1, 2);
- bar(1, 2, 3); //~ ERROR this function takes
+ bar(1, 2, 3); //~ ERROR function takes
}
fn main() {
let _: Result<(), String> = Ok(); //~ ERROR this enum variant takes
- foo(); //~ ERROR this function takes
- foo(()); //~ ERROR this function takes
- bar(); //~ ERROR this function takes
- S.baz(); //~ ERROR this function takes
- S.generic::<()>(); //~ ERROR this function takes
+ foo(); //~ ERROR function takes
+ foo(()); //~ ERROR function takes
+ bar(); //~ ERROR function takes
+ S.baz(); //~ ERROR this method takes
+ S.generic::<()>(); //~ ERROR this method takes
}
LL | bar(());
| ~~~~
-error[E0061]: this function takes 1 argument but 0 arguments were supplied
+error[E0061]: this method takes 1 argument but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:15:7
|
LL | S.baz();
LL | S.baz(());
| ~~~~
-error[E0061]: this function takes 1 argument but 0 arguments were supplied
+error[E0061]: this method takes 1 argument but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:16:7
|
LL | S.generic::<()>();
let _: Option<(i32, bool)> = Some(1, 2);
//~^ ERROR this enum variant takes 1 argument but 2 arguments were supplied
int_bool(1, 2);
- //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+ //~^ ERROR function takes 1 argument but 2 arguments were supplied
let _: Option<(i8,)> = Some();
//~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
fn main() {
let _: Result<(i32, i8), ()> = Ok((1, 2));
- //~^ ERROR this enum variant takes 1 argument but 2 arguments were supplied
+ //~^ ERROR enum variant takes 1 argument but 2 arguments were supplied
let _: Option<(i32, i8, &'static str)> = Some((1, 2, "hi"));
- //~^ ERROR this enum variant takes 1 argument but 3 arguments were supplied
+ //~^ ERROR enum variant takes 1 argument but 3 arguments were supplied
let _: Option<()> = Some(());
- //~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
+ //~^ ERROR enum variant takes 1 argument but 0 arguments were supplied
let _: Option<(i32,)> = Some((3,));
//~^ ERROR mismatched types
let _: Option<(i32,)> = Some((3,));
//~^ ERROR mismatched types
- two_ints((1, 2)); //~ ERROR this function takes 1 argument
+ two_ints((1, 2)); //~ ERROR function takes 1 argument
- with_generic((3, 4)); //~ ERROR this function takes 1 argument
+ with_generic((3, 4)); //~ ERROR function takes 1 argument
}
fn two_ints(_: (i32, i32)) {
fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
if false {
// test generics/bound handling
- with_generic((a, b)); //~ ERROR this function takes 1 argument
+ with_generic((a, b)); //~ ERROR function takes 1 argument
}
}
fn main() {
let _: Result<(i32, i8), ()> = Ok(1, 2);
- //~^ ERROR this enum variant takes 1 argument but 2 arguments were supplied
+ //~^ ERROR enum variant takes 1 argument but 2 arguments were supplied
let _: Option<(i32, i8, &'static str)> = Some(1, 2, "hi");
- //~^ ERROR this enum variant takes 1 argument but 3 arguments were supplied
+ //~^ ERROR enum variant takes 1 argument but 3 arguments were supplied
let _: Option<()> = Some();
- //~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
+ //~^ ERROR enum variant takes 1 argument but 0 arguments were supplied
let _: Option<(i32,)> = Some(3);
//~^ ERROR mismatched types
let _: Option<(i32,)> = Some((3));
//~^ ERROR mismatched types
- two_ints(1, 2); //~ ERROR this function takes 1 argument
+ two_ints(1, 2); //~ ERROR function takes 1 argument
- with_generic(3, 4); //~ ERROR this function takes 1 argument
+ with_generic(3, 4); //~ ERROR function takes 1 argument
}
fn two_ints(_: (i32, i32)) {
fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
if false {
// test generics/bound handling
- with_generic(a, b); //~ ERROR this function takes 1 argument
+ with_generic(a, b); //~ ERROR function takes 1 argument
}
}
-error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
+error[E0061]: enum variant takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple.rs:7:36
|
LL | let _: Result<(i32, i8), ()> = Ok(1, 2);
LL | let _: Result<(i32, i8), ()> = Ok((1, 2));
| + +
-error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied
+error[E0061]: enum variant takes 1 argument but 3 arguments were supplied
--> $DIR/args-instead-of-tuple.rs:9:46
|
LL | let _: Option<(i32, i8, &'static str)> = Some(1, 2, "hi");
LL | let _: Option<(i32,)> = Some((3,));
| +
-error[E0061]: this function takes 1 argument but 2 arguments were supplied
+error[E0061]: function takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple.rs:20:5
|
LL | two_ints(1, 2);
LL | two_ints((1, 2));
| + +
-error[E0061]: this function takes 1 argument but 2 arguments were supplied
+error[E0061]: function takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple.rs:22:5
|
LL | with_generic(3, 4);
LL | with_generic((3, 4));
| + +
-error[E0061]: this function takes 1 argument but 2 arguments were supplied
+error[E0061]: function takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple.rs:31:9
|
LL | with_generic(a, b);
fn two_type_params<A, B>(_: B) {}
fn main() {
- two_type_params::<String, _>(100); //~ ERROR this function takes 2 generic arguments
+ two_type_params::<String, _>(100); //~ ERROR function takes 2 generic arguments
two_type_params::<String, _>(100);
}
fn two_type_params<A, B>(_: B) {}
fn main() {
- two_type_params::<String>(100); //~ ERROR this function takes 2 generic arguments
+ two_type_params::<String>(100); //~ ERROR function takes 2 generic arguments
two_type_params::<String, _>(100);
}
LL | let _s = y.unwrap_or(|| x.split('.').nth(1).unwrap());
| --------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found closure
| |
- | arguments to this function are incorrect
+ | arguments to this method are incorrect
|
= note: expected reference `&str`
found closure `[closure@$DIR/sugg-else-for-closure.rs:6:26: 6:28]`
LL | x.funk(3);
| ---- ^ expected associated type, found integer
| |
- | arguments to this function are incorrect
+ | arguments to this method are incorrect
|
= note: expected associated type `<T as Trait<i32>>::A`
found type `{integer}`
LL | builder.push(output);
| ---- ^^^^^^ expected type parameter `F`, found struct `Class`
| |
- | arguments to this function are incorrect
+ | arguments to this method are incorrect
|
= note: expected type parameter `F`
found struct `Class<P>`
--- /dev/null
+struct Argument;
+struct Return;
+
+fn function(_: Argument) -> Return { todo!() }
+
+trait Trait {}
+impl Trait for fn(Argument) -> Return {}
+
+fn takes(_: impl Trait) {}
+
+fn main() {
+ takes(function);
+ //~^ ERROR the trait bound
+ takes(|_: Argument| -> Return { todo!() });
+ //~^ ERROR the trait bound
+}
--- /dev/null
+error[E0277]: the trait bound `fn(Argument) -> Return {function}: Trait` is not satisfied
+ --> $DIR/issue-99875.rs:12:11
+ |
+LL | takes(function);
+ | ----- ^^^^^^^^ the trait `Trait` is not implemented for fn item `fn(Argument) -> Return {function}`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return`
+note: required by a bound in `takes`
+ --> $DIR/issue-99875.rs:9:18
+ |
+LL | fn takes(_: impl Trait) {}
+ | ^^^^^ required by this bound in `takes`
+
+error[E0277]: the trait bound `[closure@$DIR/issue-99875.rs:14:11: 14:34]: Trait` is not satisfied
+ --> $DIR/issue-99875.rs:14:11
+ |
+LL | takes(|_: Argument| -> Return { todo!() });
+ | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for closure `[closure@$DIR/issue-99875.rs:14:11: 14:34]`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return`
+note: required by a bound in `takes`
+ --> $DIR/issue-99875.rs:9:18
+ |
+LL | fn takes(_: impl Trait) {}
+ | ^^^^^ required by this bound in `takes`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
fn main() {
foo("hi", 1, 2, "hi");
- //~^ ERROR this function takes 3 arguments but 4 arguments were supplied
+ //~^ ERROR function takes 3 arguments but 4 arguments were supplied
bar("hi", "hi", "hi");
//~^ ERROR mismatched types
}
-error[E0061]: this function takes 3 arguments but 4 arguments were supplied
+error[E0061]: function takes 3 arguments but 4 arguments were supplied
--> $DIR/add-tuple-within-arguments.rs:6:5
|
LL | foo("hi", 1, 2, "hi");
fn bar() {
let x = Foo;
test(x.qux(), x.qux());
- //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+ //~^ ERROR function takes 1 argument but 2 arguments were supplied
}
fn main() {}
-error[E0061]: this function takes 1 argument but 2 arguments were supplied
+error[E0061]: function takes 1 argument but 2 arguments were supplied
--> $DIR/wrong_argument_ice-2.rs:13:5
|
LL | test(x.qux(), x.qux());
if groups.capacity() == 0 {
groups.push(new_group, vec![process]);
- //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+ //~^ ERROR this method takes 1 argument but 2 arguments were supplied
return groups;
}
-error[E0061]: this function takes 1 argument but 2 arguments were supplied
+error[E0061]: this method takes 1 argument but 2 arguments were supplied
--> $DIR/wrong_argument_ice-3.rs:9:16
|
LL | groups.push(new_group, vec![process]);
fn main() {
(|| {})(|| {
- //~^ ERROR this function takes 0 arguments but 1 argument was supplied
+ //~^ ERROR function takes 0 arguments but 1 argument was supplied
let b = 1;
});
}
impl BuildPlanBuilder {
pub fn or(&mut self) -> &mut Self {
self.acc.push_back(self.current_provides, self.current_requires);
- //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+ //~^ ERROR method takes 1 argument but 2 arguments were supplied
self
}
}
-error[E0061]: this function takes 1 argument but 2 arguments were supplied
+error[E0061]: method takes 1 argument but 2 arguments were supplied
--> $DIR/wrong_argument_ice.rs:11:18
|
LL | self.acc.push_back(self.current_provides, self.current_requires);
--- /dev/null
+#![crate_type = "lib"]
+
+pub fn foo(callback: fn() -> dyn ToString) {
+ let mut x: Option<Box<dyn Fn() -> dyn ToString>> = None;
+ x = Some(Box::new(callback));
+ //~^ ERROR: the size for values of type `dyn ToString` cannot be known at compilation time
+}
--- /dev/null
+error[E0277]: the size for values of type `dyn ToString` cannot be known at compilation time
+ --> $DIR/issue-58355.rs:5:14
+ |
+LL | x = Some(Box::new(callback));
+ | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: within `fn() -> dyn ToString`, the trait `Sized` is not implemented for `dyn ToString`
+ = note: required because it appears within the type `fn() -> dyn ToString`
+ = note: required for the cast from `fn() -> dyn ToString` to the object type `dyn Fn() -> (dyn ToString + 'static)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
fn main() {
let x: Vec::with_capacity(10, 20); //~ ERROR expected type, found `10`
- //~^ ERROR this function takes 1 argument
+ //~^ ERROR function takes 1 argument
}
error[E0308]: mismatched types
--> $DIR/assignment-in-if.rs:44:18
|
+LL | if y = (Foo { foo: x }) {
+ | - here the type of `x` is inferred to be `usize`
+...
LL | if x == x && x = x && x == x {
| ------ ^ expected `bool`, found `usize`
| |
error[E0308]: mismatched types
--> $DIR/assignment-in-if.rs:44:22
|
+LL | if y = (Foo { foo: x }) {
+ | - here the type of `x` is inferred to be `usize`
+...
LL | if x == x && x = x && x == x {
| ^ expected `bool`, found `usize`
error[E0308]: mismatched types
--> $DIR/assignment-in-if.rs:51:28
|
+LL | if y = (Foo { foo: x }) {
+ | - here the type of `x` is inferred to be `usize`
+...
LL | if x == x && x == x && x = x {
| ---------------- ^ expected `bool`, found `usize`
| |
--- /dev/null
+fn bar(_: Vec<i32>) {}
+fn baz(_: &Vec<&i32>) {}
+fn main() {
+ let v = vec![&1];
+ bar(v); //~ ERROR E0308
+ let v = vec![];
+ baz(&v);
+ baz(&v);
+ bar(v); //~ ERROR E0308
+ let v = vec![];
+ baz(&v);
+ bar(v); //~ ERROR E0308
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/point-at-inference-2.rs:5:9
+ |
+LL | bar(v);
+ | --- ^ expected `i32`, found `&{integer}`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected struct `Vec<i32>`
+ found struct `Vec<&{integer}>`
+note: function defined here
+ --> $DIR/point-at-inference-2.rs:1:4
+ |
+LL | fn bar(_: Vec<i32>) {}
+ | ^^^ -----------
+
+error[E0308]: mismatched types
+ --> $DIR/point-at-inference-2.rs:9:9
+ |
+LL | baz(&v);
+ | - here the type of `v` is inferred to be `Vec<&i32>`
+LL | baz(&v);
+LL | bar(v);
+ | --- ^ expected `i32`, found `&i32`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected struct `Vec<i32>`
+ found struct `Vec<&i32>`
+note: function defined here
+ --> $DIR/point-at-inference-2.rs:1:4
+ |
+LL | fn bar(_: Vec<i32>) {}
+ | ^^^ -----------
+
+error[E0308]: mismatched types
+ --> $DIR/point-at-inference-2.rs:12:9
+ |
+LL | baz(&v);
+ | - here the type of `v` is inferred to be `Vec<&i32>`
+LL | bar(v);
+ | --- ^ expected `i32`, found `&i32`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected struct `Vec<i32>`
+ found struct `Vec<&i32>`
+note: function defined here
+ --> $DIR/point-at-inference-2.rs:1:4
+ |
+LL | fn bar(_: Vec<i32>) {}
+ | ^^^ -----------
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+// run-rustfix
+fn main() {
+ let mut v = Vec::new();
+ v.push(0i32);
+ //~^ NOTE this is of type `i32`, which causes `v` to be inferred as `Vec<i32>`
+ v.push(0);
+ v.push(1i32); //~ ERROR mismatched types
+ //~^ NOTE expected `i32`, found `u32`
+ //~| NOTE arguments to this method are incorrect
+ //~| NOTE associated function defined here
+ //~| HELP change the type of the numeric literal from `u32` to `i32`
+}
--- /dev/null
+// run-rustfix
+fn main() {
+ let mut v = Vec::new();
+ v.push(0i32);
+ //~^ NOTE this is of type `i32`, which causes `v` to be inferred as `Vec<i32>`
+ v.push(0);
+ v.push(1u32); //~ ERROR mismatched types
+ //~^ NOTE expected `i32`, found `u32`
+ //~| NOTE arguments to this method are incorrect
+ //~| NOTE associated function defined here
+ //~| HELP change the type of the numeric literal from `u32` to `i32`
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/point-at-inference-3.rs:7:12
+ |
+LL | v.push(0i32);
+ | ---- this is of type `i32`, which causes `v` to be inferred as `Vec<i32>`
+...
+LL | v.push(1u32);
+ | ---- ^^^^ expected `i32`, found `u32`
+ | |
+ | arguments to this method are incorrect
+ |
+note: associated function defined here
+ --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | v.push(1i32);
+ | ~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+// run-rustfix
+fn bar(_: Vec<i32>) {}
+fn baz(_: &impl std::any::Any) {}
+fn main() {
+ let v = vec![1, 2, 3, 4, 5];
+ let mut foo = vec![];
+ baz(&foo);
+ for i in &v {
+ foo.push(*i);
+ }
+ baz(&foo);
+ bar(foo); //~ ERROR E0308
+}
--- /dev/null
+// run-rustfix
+fn bar(_: Vec<i32>) {}
+fn baz(_: &impl std::any::Any) {}
+fn main() {
+ let v = vec![1, 2, 3, 4, 5];
+ let mut foo = vec![];
+ baz(&foo);
+ for i in &v {
+ foo.push(i);
+ }
+ baz(&foo);
+ bar(foo); //~ ERROR E0308
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/point-at-inference.rs:12:9
+ |
+LL | foo.push(i);
+ | - this is of type `&{integer}`, which causes `foo` to be inferred as `Vec<&{integer}>`
+...
+LL | bar(foo);
+ | --- ^^^ expected `i32`, found `&{integer}`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected struct `Vec<i32>`
+ found struct `Vec<&{integer}>`
+note: function defined here
+ --> $DIR/point-at-inference.rs:2:4
+ |
+LL | fn bar(_: Vec<i32>) {}
+ | ^^^ -----------
+help: consider dereferencing the borrow
+ |
+LL | foo.push(*i);
+ | +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+// run-pass
+// Test that we are able to type-check this example. In particular,
+// knowing that `T: 'a` allows us to deduce that `[U]: 'a` (because
+// when `T=[U]` it implies that `U: 'a`).
+//
+// Regr. test for live code we found in the wild when fixing #18937.
+
+pub trait Leak<T : ?Sized> {
+ fn leak<'a>(self) -> &'a T where T: 'a;
+}
+
+impl<U> Leak<[U]> for Vec<U> {
+ fn leak<'a>(mut self) -> &'a [U] where [U]: 'a {
+ let r: *mut [U] = &mut self[..];
+ std::mem::forget(self);
+ unsafe { &mut *r }
+ }
+}
+fn main() {
+ println!("Hello, world!");
+}
--- /dev/null
+// Regression test for #18937.
+
+use std::fmt;
+
+#[derive(Debug)]
+struct MyString<'a>(&'a String);
+
+struct B {
+ list: Vec<Box<dyn fmt::Debug>>,
+}
+
+trait A<'a> {
+ fn foo<F>(&mut self, f: F)
+ where F: fmt::Debug + 'a,
+ Self: Sized;
+}
+
+impl<'a> A<'a> for B {
+ fn foo<F>(&mut self, f: F)
+ where F: fmt::Debug + 'static, //~ ERROR impl has stricter
+ {
+ self.list.push(Box::new(f));
+ }
+}
+
+fn main() {
+ let mut b = B { list: Vec::new() };
+
+ // Create a borrowed pointer, put it in `b`, then drop what's borrowing it
+ let a = "hello".to_string();
+ b.foo(MyString(&a));
+
+ // Drop the data which `b` has a reference to
+ drop(a);
+
+ // Use the data, probably segfaulting
+ for b in b.list.iter() {
+ println!("{:?}", b);
+ }
+}
--- /dev/null
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/issue-18937.rs:20:31
+ |
+LL | / fn foo<F>(&mut self, f: F)
+LL | | where F: fmt::Debug + 'a,
+LL | | Self: Sized;
+ | |__________________________- definition of `foo` from trait
+...
+LL | where F: fmt::Debug + 'static,
+ | ^^^^^^^ impl has extra requirement `F: 'static`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0276`.
--- /dev/null
+use std::vec::IntoIter;
+
+pub fn get_tok(it: &mut IntoIter<u8>) {
+ let mut found_e = false;
+
+ let temp: Vec<u8> = it
+ .take_while(|&x| {
+ found_e = true;
+ false
+ })
+ .cloned() //~ ERROR to be an iterator that yields `&_`, but it yields `u8`
+ .collect(); //~ ERROR the method
+}
+
+fn main() {}
--- /dev/null
+error[E0271]: expected `TakeWhile<&mut IntoIter<u8>, [closure@issue-31173.rs:7:21]>` to be an iterator that yields `&_`, but it yields `u8`
+ --> $DIR/issue-31173.rs:11:10
+ |
+LL | .cloned()
+ | ^^^^^^ expected reference, found `u8`
+ |
+ = note: expected reference `&_`
+ found type `u8`
+note: the method call chain might not have had the expected associated types
+ --> $DIR/issue-31173.rs:3:20
+ |
+LL | pub fn get_tok(it: &mut IntoIter<u8>) {
+ | ^^^^^^^^^^^^^^^^^ `Iterator::Item` is `u8` here
+...
+LL | .take_while(|&x| {
+ | __________-
+LL | | found_e = true;
+LL | | false
+LL | | })
+ | |__________- `Iterator::Item` remains `u8` here
+note: required by a bound in `cloned`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut IntoIter<u8>, [closure@issue-31173.rs:7:21]>>`, but its trait bounds were not satisfied
+ --> $DIR/issue-31173.rs:12:10
+ |
+LL | .collect();
+ | ^^^^^^^ method cannot be called due to unsatisfied trait bounds
+ --> $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
+ |
+ = note: doesn't satisfy `<_ as Iterator>::Item = &_`
+ --> $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
+ |
+ = note: doesn't satisfy `_: Iterator`
+ |
+ = note: the following trait bounds were not satisfied:
+ `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_`
+ which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
+ `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
+ which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0271, E0599.
+For more information about an error, try `rustc --explain E0271`.
fn main() {
l(vec![])
- //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+ //~^ ERROR function takes 1 argument but 2 arguments were supplied
//~| HELP remove the extra argument
}
fn main() {
l(vec![], vec![])
- //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+ //~^ ERROR function takes 1 argument but 2 arguments were supplied
//~| HELP remove the extra argument
}
--> $DIR/unboxed-closure-no-cyclic-sig.rs:8:7
|
LL | g(|_| { });
- | ^^^^^^^^ cyclic type of infinite size
+ | ^^^ cyclic type of infinite size
|
= note: closures cannot capture themselves or take themselves as argument;
this error may be the result of a recent compiler bug-fix,
see issue #46062 <https://github.com/rust-lang/rust/issues/46062>
for more information
+note: required by a bound in `g`
+ --> $DIR/unboxed-closure-no-cyclic-sig.rs:5:24
+ |
+LL | fn g<F>(_: F) where F: FnOnce(Option<F>) {}
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `g`
error: aborting due to previous error
-Subproject commit 2381cbdb4e9b07090f552d34a44a529b6e620e44
+Subproject commit 8c460b2237a6359a7e3335890db8da049bdd62fc
fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let map = cx.tcx.hir();
if_chain! {
- if let Some(parent_id) = map.find_parent_node(expr.hir_id);
+ if let Some(parent_id) = map.opt_parent_id(expr.hir_id);
if let Some(parent) = map.find(parent_id);
then {
let expr = match parent {
_ => return false,
}
- matches!(map.find(map.get_parent_node(id)), Some(Node::Param(_)))
+ matches!(map.find_parent(id), Some(Node::Param(_)))
}
impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
let map = &self.cx.tcx.hir();
if is_argument(*map, cmt.hir_id) {
// Skip closure arguments
- let parent_id = map.get_parent_node(cmt.hir_id);
- if let Some(Node::Expr(..)) = map.find(map.get_parent_node(parent_id)) {
+ let parent_id = map.parent_id(cmt.hir_id);
+ if let Some(Node::Expr(..)) = map.find_parent(parent_id) {
return;
}
let map = cx.tcx.hir();
// Checking for slice indexing
- let parent_id = map.get_parent_node(expr.hir_id);
+ let parent_id = map.parent_id(expr.hir_id);
if let Some(hir::Node::Expr(parent_expr)) = map.find(parent_id);
if let hir::ExprKind::Index(_, index_expr) = parent_expr.kind;
if let Some((Constant::Int(index_value), _)) = constant(cx, cx.typeck_results(), index_expr);
if index_value < max_suggested_slice;
// Make sure that this slice index is read only
- let maybe_addrof_id = map.get_parent_node(parent_id);
+ let maybe_addrof_id = map.parent_id(parent_id);
if let Some(hir::Node::Expr(maybe_addrof_expr)) = map.find(maybe_addrof_id);
if let hir::ExprKind::AddrOf(_kind, hir::Mutability::Not, _inner_expr) = maybe_addrof_expr.kind;
then {
if let Node::Pat(pat) = node;
if let PatKind::Binding(bind_ann, ..) = pat.kind;
if !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut));
- let parent_node = cx.tcx.hir().get_parent_node(hir_id);
+ let parent_node = cx.tcx.hir().parent_id(hir_id);
if let Some(Node::Local(parent_let_expr)) = cx.tcx.hir().find(parent_node);
if let Some(init) = parent_let_expr.init;
then {
&& let Some(hir_id) = path_to_local(expr3)
&& let Some(Node::Pat(_)) = cx.tcx.hir().find(hir_id) {
// Apply only to params or locals with annotated types
- match cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
+ match cx.tcx.hir().find_parent(hir_id) {
Some(Node::Param(..)) => (),
Some(Node::Local(local)) => {
let Some(ty) = local.ty else { return };
fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<AssignmentExpr> {
let map = &cx.tcx.hir();
- if let Some(Node::Expr(parent_arm_expr)) = map.find(map.get_parent_node(ex.hir_id)) {
- return match map.find(map.get_parent_node(parent_arm_expr.hir_id)) {
+ if let Some(Node::Expr(parent_arm_expr)) = map.find_parent(ex.hir_id) {
+ return match map.find_parent(parent_arm_expr.hir_id) {
Some(Node::Local(parent_let_expr)) => Some(AssignmentExpr::Local {
span: parent_let_expr.span,
pat_span: parent_let_expr.pat.span(),
// If the parent is already an arm, and the body is another match statement,
// we need curly braces around suggestion
- let parent_node_id = cx.tcx.hir().get_parent_node(match_expr.hir_id);
- if let Node::Arm(arm) = &cx.tcx.hir().get(parent_node_id) {
+ if let Node::Arm(arm) = &cx.tcx.hir().get_parent(match_expr.hir_id) {
if let ExprKind::Match(..) = arm.body.kind {
cbrace_end = format!("\n{indent}}}");
// Fix body indent due to the match
let map = &vis.cx.tcx.hir();
let mut cur_id = vis.write_expr.hir_id;
loop {
- let parent_id = map.get_parent_node(cur_id);
+ let parent_id = map.parent_id(cur_id);
if parent_id == cur_id {
break;
}
}
// Exclude non-inherent impls
- if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
+ if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
if matches!(
item.kind,
ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)
let mut dereferenced_expr = expr;
let mut needs_check_adjustment = true;
loop {
- let parent_id = cx.tcx.hir().get_parent_node(cur_expr.hir_id);
+ let parent_id = cx.tcx.hir().parent_id(cur_expr.hir_id);
if parent_id == cur_expr.hir_id {
break;
}
}
// Exclude non-inherent impls
- if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
+ if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
if matches!(
item.kind,
ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)
return;
}
let map = &cx.tcx.hir();
- let opt_parent_node = map.find(map.get_parent_node(expr.hir_id));
+ let opt_parent_node = map.find_parent(expr.hir_id);
if_chain! {
if let Some(hir::Node::Expr(parent_expr)) = opt_parent_node;
if is_questionmark_desugar_marked_call(parent_expr);
let mut stmts_and_call_snippet = stmts_and_call.join(&format!("{}{}", ";\n", " ".repeat(call_expr_indent)));
// expr is not in a block statement or result expression position, wrap in a block
- let parent_node = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(call_expr.hir_id));
+ let parent_node = cx.tcx.hir().find_parent(call_expr.hir_id);
if !matches!(parent_node, Some(Node::Block(_))) && !matches!(parent_node, Some(Node::Stmt(_))) {
let block_indent = call_expr_indent + 4;
stmts_and_call_snippet =
}
// Abort if the method is implementing a trait or of it a trait method.
- if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
+ if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
if matches!(
item.kind,
ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)
fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::Local<'hir>> {
let map = cx.tcx.hir();
- match map.find(map.get_parent_node(hir_id)) {
+ match map.find_parent((hir_id)) {
Some(hir::Node::Local(local)) => Some(local),
Some(hir::Node::Pat(pattern)) => get_parent_local_hir_id(cx, pattern.hir_id),
_ => None,
match peel_hir_expr_refs(expr).0.kind {
ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) {
Res::Local(hir_id) => {
- let parent_id = cx.tcx.hir().get_parent_node(hir_id);
+ let parent_id = cx.tcx.hir().parent_id(hir_id);
if let Some(Node::Local(Local { init: Some(init), .. })) = cx.tcx.hir().find(parent_id) {
path_to_matched_type(cx, init)
} else {
if_chain! {
if let Some(Node::Pat(pat)) = hir.find(hir_id);
if matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..));
- let parent = hir.get_parent_node(hir_id);
+ let parent = hir.parent_id(hir_id);
if let Some(Node::Local(local)) = hir.find(parent);
then {
return local.init;
/// Gets the parent node, if any.
pub fn get_parent_node(tcx: TyCtxt<'_>, id: HirId) -> Option<Node<'_>> {
- tcx.hir().parent_iter(id).next().map(|(_, node)| node)
+ tcx.hir().find_parent(id)
}
/// Gets the parent expression, if any –- this is useful to constrain a lint.
/// }
/// ```
pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool {
- if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
+ if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))
} else {
false
rustc.args(&["-Zpolonius"]);
}
Some(CompareMode::Chalk) => {
- rustc.args(&["-Zchalk"]);
+ rustc.args(&["-Ztrait-solver=chalk"]);
}
Some(CompareMode::SplitDwarf) if self.config.target.contains("windows") => {
rustc.args(&["-Csplit-debuginfo=unpacked", "-Zunstable-options"]);
git-repository-url = "https://github.com/rust-lang/rust/"
additional-css = ["error-index.css"]
additional-js = ["error-index.js"]
+input-404 = ""
[output.html.search]
enable = true
fn render_html(output_path: &Path) -> Result<(), Box<dyn Error>> {
let mut introduction = format!(
- "<script src='redirect.js'></script>
-# Rust error codes index
+ "# Rust error codes index
This page lists all the error codes emitted by the Rust compiler.
book.book.sections.push(BookItem::Chapter(chapter));
book.build()?;
- // We can't put this content into another file, otherwise `mbdbook` will also put it into the
+ // The error-index used to be generated manually (without mdbook), and the
+ // index was located at the top level. Now that it is generated with
+ // mdbook, error-index.html has moved to error_codes/error-index.html.
+ // This adds a redirect so that old links go to the new location.
+ //
+ // We can't put this content into another file, otherwise `mdbook` will also put it into the
// output directory, making a duplicate.
fs::write(
output_path.join("error-index.html"),
</head>
<body>
<div>If you are not automatically redirected to the error code index, please <a id="index-link" href="./error_codes/error-index.html">here</a>.
- <script>document.getElementById("index-link").click()</script>
</body>
</html>"#,
)?;
- // No need for a 404 file, it's already handled by the server.
- fs::remove_file(output_path.join("error_codes/404.html"))?;
-
Ok(())
}
let code = window.location.hash.replace(/^#/, '');
// We have to make sure this pattern matches to avoid inadvertently creating an
// open redirect.
- if (!/^E[0-9]+$/.test(code)) {
+ if (/^E[0-9]+$/.test(code)) {
+ window.location.replace('./error_codes/' + code + '.html');
return;
}
- if (window.location.pathname.indexOf("/error_codes/") !== -1) {
- // We're not at the top level, so we don't prepend with "./error_codes/".
- window.location = './' + code + '.html';
- } else {
- window.location = './error_codes/' + code + '.html';
- }
}
+ window.location.replace('./error_codes/error-index.html');
})()
curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true }
# Ensure `extra_traits` of libc, which is used transitively by Cargo.
libc = { version = "0.2", features = ["extra_traits"] }
+# Ensure `js` of getrandom, which is (unfortunately) used transitively by Cargo.
+getrandom = { version = "0.2", features = ["js"] }
# Ensure default features of libz-sys, which are disabled in some scenarios.
libz-sys = { version = "1.1.2" }
# Ensure default features of regex, which are disabled in some scenarios.
("im-rc", "MPL-2.0+"), // cargo
("sized-chunks", "MPL-2.0+"), // cargo via im-rc
("bitmaps", "MPL-2.0+"), // cargo via im-rc
+ ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"), // cargo via pasetors
+ ("subtle", "BSD-3-Clause"), // cargo via pasetors
("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
("snap", "BSD-3-Clause"), // rustc
("fluent-langneg", "Apache-2.0"), // rustc (fluent translations)
"autocfg",
"bitflags",
"block-buffer",
+ "bumpalo", // Included in Cargo's dep graph but only activated on wasm32-*-unknown.
"cc",
"cfg-if",
"chalk-derive",
"itertools",
"itoa",
"jobserver",
+ "js-sys", // Included in Cargo's dep graph but only activated on wasm32-*-unknown.
"lazy_static",
"libc",
"libloading",
"stable_deref_trait",
"stacker",
"static_assertions",
+ "subtle", // dependency of cargo (via pasetors)
"syn",
"synstructure",
"tempfile",
"valuable",
"version_check",
"wasi",
+ // vvv Included in Cargo's dep graph but only activated on wasm32-*-unknown.
+ "wasm-bindgen",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-macro",
+ "wasm-bindgen-macro-support",
+ "wasm-bindgen-shared",
+ // ^^^ Included in Cargo's dep graph but only activated on wasm32-*-unknown.
"winapi",
"winapi-i686-pc-windows-gnu",
"winapi-util",
const ENTRY_LIMIT: usize = 1000;
// FIXME: The following limits should be reduced eventually.
const ROOT_ENTRY_LIMIT: usize = 939;
-const ISSUES_ENTRY_LIMIT: usize = 2050;
+const ISSUES_ENTRY_LIMIT: usize = 1998;
fn check_entries(path: &Path, bad: &mut bool) {
for dir in Walk::new(&path.join("test/ui")) {