Skip to content
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
82684ad
Added long error description & modifed error_codes.rs
jwhite927 Feb 5, 2020
4a1c6ce
Added long error description & modifed error_codes.rs
jwhite927 Feb 5, 2020
201a262
Revised error long description
jwhite927 Feb 6, 2020
cdf2f30
Merge branch 'E0637' of https://github.com/jwhite927/rust into E0637
jwhite927 Feb 6, 2020
1923586
Edited error description
jwhite927 Feb 6, 2020
78df446
Tidied up the long error description
jwhite927 Feb 6, 2020
8b77f86
performed --bless of 15 ui tests affected
jwhite927 Feb 7, 2020
92fc98c
Cleaned up long error description
jwhite927 Feb 8, 2020
69075f0
Merge branch 'master' of https://github.com/jwhite927/rust into E0637
jwhite927 Feb 8, 2020
4091466
Removed trailing white spaces
jwhite927 Feb 8, 2020
58d0e67
Added compiler flags to example code, removed unexpected curly
jwhite927 Feb 8, 2020
a804d47
Corrected E0637.md based on test failure
jwhite927 Feb 8, 2020
8c35118
Corrected E0637.md based on test failures
jwhite927 Feb 8, 2020
9d54bb2
Tidied up E0637.md
jwhite927 Feb 8, 2020
d705ad2
Merge branch 'master' of https://github.com/jwhite927/rust into E0637
jwhite927 Feb 8, 2020
a9212b8
Make the ASCII ctype inherent methods const
ecstatic-morse Feb 9, 2020
ea95842
Test ASCII ctype methods in a const context
ecstatic-morse Feb 9, 2020
371060b
[parser] change an instance of span_bug() to struct_span_err() to avo…
dwrensha Feb 10, 2020
ded6292
Clean up E0283 explanation
GuillaumeGomez Feb 9, 2020
37e7b46
clean up E0275 explanation
GuillaumeGomez Feb 6, 2020
81dccb1
self-profile: Support arguments for generic_activities.
michaelwoerister Feb 7, 2020
1e26a1c
Rollup merge of #68897 - GuillaumeGomez:clean-up-e0275, r=Dylan-DPC
Dylan-DPC Feb 10, 2020
531f235
Rollup merge of #68908 - jwhite927:E0637, r=Dylan-DPC
Dylan-DPC Feb 10, 2020
24260e5
Rollup merge of #68932 - michaelwoerister:self-profile-generic-activi…
Dylan-DPC Feb 10, 2020
6e1b75b
Rollup merge of #68986 - ecstatic-morse:const-ascii-ctype, r=Centril
Dylan-DPC Feb 10, 2020
db08784
Rollup merge of #69007 - GuillaumeGomez:clean-up-e0283, r=Dylan-DPC
Dylan-DPC Feb 10, 2020
119bc97
Rollup merge of #69014 - dwrensha:fix-68890, r=Centril
Dylan-DPC Feb 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions src/libcore/char/methods.rs
Original file line number Diff line number Diff line change
@@ -1072,8 +1072,9 @@ impl char {
/// assert!(!esc.is_ascii_alphabetic());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_alphabetic(&self) -> bool {
pub const fn is_ascii_alphabetic(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_alphabetic()
}

@@ -1104,8 +1105,9 @@ impl char {
/// assert!(!esc.is_ascii_uppercase());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_uppercase(&self) -> bool {
pub const fn is_ascii_uppercase(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_uppercase()
}

@@ -1136,8 +1138,9 @@ impl char {
/// assert!(!esc.is_ascii_lowercase());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_lowercase(&self) -> bool {
pub const fn is_ascii_lowercase(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_lowercase()
}

@@ -1171,8 +1174,9 @@ impl char {
/// assert!(!esc.is_ascii_alphanumeric());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_alphanumeric(&self) -> bool {
pub const fn is_ascii_alphanumeric(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_alphanumeric()
}

@@ -1203,8 +1207,9 @@ impl char {
/// assert!(!esc.is_ascii_digit());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_digit(&self) -> bool {
pub const fn is_ascii_digit(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_digit()
}

@@ -1238,8 +1243,9 @@ impl char {
/// assert!(!esc.is_ascii_hexdigit());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_hexdigit(&self) -> bool {
pub const fn is_ascii_hexdigit(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_hexdigit()
}

@@ -1274,8 +1280,9 @@ impl char {
/// assert!(!esc.is_ascii_punctuation());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_punctuation(&self) -> bool {
pub const fn is_ascii_punctuation(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_punctuation()
}

@@ -1306,8 +1313,9 @@ impl char {
/// assert!(!esc.is_ascii_graphic());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_graphic(&self) -> bool {
pub const fn is_ascii_graphic(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_graphic()
}

@@ -1355,8 +1363,9 @@ impl char {
/// assert!(!esc.is_ascii_whitespace());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_whitespace(&self) -> bool {
pub const fn is_ascii_whitespace(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_whitespace()
}

@@ -1389,8 +1398,9 @@ impl char {
/// assert!(esc.is_ascii_control());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_control(&self) -> bool {
pub const fn is_ascii_control(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_control()
}
}
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
@@ -70,6 +70,7 @@
#![feature(bound_cloned)]
#![feature(cfg_target_has_atomic)]
#![feature(concat_idents)]
#![feature(const_ascii_ctype_on_intrinsics)]
#![feature(const_alloc_layout)]
#![feature(const_if_match)]
#![feature(const_checked_int_methods)]
30 changes: 20 additions & 10 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
@@ -4449,8 +4449,9 @@ impl u8 {
/// assert!(!esc.is_ascii_alphabetic());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_alphabetic(&self) -> bool {
pub const fn is_ascii_alphabetic(&self) -> bool {
matches!(*self, b'A'..=b'Z' | b'a'..=b'z')
}

@@ -4481,8 +4482,9 @@ impl u8 {
/// assert!(!esc.is_ascii_uppercase());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_uppercase(&self) -> bool {
pub const fn is_ascii_uppercase(&self) -> bool {
matches!(*self, b'A'..=b'Z')
}

@@ -4513,8 +4515,9 @@ impl u8 {
/// assert!(!esc.is_ascii_lowercase());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_lowercase(&self) -> bool {
pub const fn is_ascii_lowercase(&self) -> bool {
matches!(*self, b'a'..=b'z')
}

@@ -4548,8 +4551,9 @@ impl u8 {
/// assert!(!esc.is_ascii_alphanumeric());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_alphanumeric(&self) -> bool {
pub const fn is_ascii_alphanumeric(&self) -> bool {
matches!(*self, b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z')
}

@@ -4580,8 +4584,9 @@ impl u8 {
/// assert!(!esc.is_ascii_digit());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_digit(&self) -> bool {
pub const fn is_ascii_digit(&self) -> bool {
matches!(*self, b'0'..=b'9')
}

@@ -4615,8 +4620,9 @@ impl u8 {
/// assert!(!esc.is_ascii_hexdigit());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_hexdigit(&self) -> bool {
pub const fn is_ascii_hexdigit(&self) -> bool {
matches!(*self, b'0'..=b'9' | b'A'..=b'F' | b'a'..=b'f')
}

@@ -4651,8 +4657,9 @@ impl u8 {
/// assert!(!esc.is_ascii_punctuation());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_punctuation(&self) -> bool {
pub const fn is_ascii_punctuation(&self) -> bool {
matches!(*self, b'!'..=b'/' | b':'..=b'@' | b'['..=b'`' | b'{'..=b'~')
}

@@ -4683,8 +4690,9 @@ impl u8 {
/// assert!(!esc.is_ascii_graphic());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_graphic(&self) -> bool {
pub const fn is_ascii_graphic(&self) -> bool {
matches!(*self, b'!'..=b'~')
}

@@ -4732,8 +4740,9 @@ impl u8 {
/// assert!(!esc.is_ascii_whitespace());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_whitespace(&self) -> bool {
pub const fn is_ascii_whitespace(&self) -> bool {
matches!(*self, b'\t' | b'\n' | b'\x0C' | b'\r' | b' ')
}

@@ -4766,8 +4775,9 @@ impl u8 {
/// assert!(esc.is_ascii_control());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
#[inline]
pub fn is_ascii_control(&self) -> bool {
pub const fn is_ascii_control(&self) -> bool {
matches!(*self, b'\0'..=b'\x1F' | b'\x7F')
}
}
6 changes: 4 additions & 2 deletions src/librustc/ty/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
@@ -1053,8 +1053,10 @@ where
Q: super::config::QueryDescription<'tcx, Value: Encodable>,
E: 'a + TyEncoder,
{
let desc = &format!("encode_query_results_for_{}", ::std::any::type_name::<Q>());
let _timer = tcx.sess.prof.extra_verbose_generic_activity(desc);
let _timer = tcx
.sess
.prof
.extra_verbose_generic_activity("encode_query_results_for", ::std::any::type_name::<Q>());

let shards = Q::query_cache(tcx).lock_shards();
assert!(shards.iter().all(|shard| shard.active.is_empty()));
57 changes: 32 additions & 25 deletions src/librustc_codegen_llvm/back/lto.rs
Original file line number Diff line number Diff line change
@@ -110,23 +110,21 @@ fn prepare_lto(
symbol_white_list.extend(exported_symbols[&cnum].iter().filter_map(symbol_filter));
}

let _timer = cgcx.prof.generic_activity("LLVM_lto_load_upstream_bitcode");
let archive = ArchiveRO::open(&path).expect("wanted an rlib");
let bytecodes = archive
.iter()
.filter_map(|child| child.ok().and_then(|c| c.name().map(|name| (name, c))))
.filter(|&(name, _)| name.ends_with(RLIB_BYTECODE_EXTENSION));
for (name, data) in bytecodes {
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_lto_load_upstream_bitcode", name);
info!("adding bytecode {}", name);
let bc_encoded = data.data();

let (bc, id) = cgcx
.prof
.extra_verbose_generic_activity(&format!("decode {}", name))
.run(|| match DecodedBytecode::new(bc_encoded) {
Ok(b) => Ok((b.bytecode(), b.identifier().to_string())),
Err(e) => Err(diag_handler.fatal(&e)),
})?;
let (bc, id) = match DecodedBytecode::new(bc_encoded) {
Ok(b) => Ok((b.bytecode(), b.identifier().to_string())),
Err(e) => Err(diag_handler.fatal(&e)),
}?;
let bc = SerializedModule::FromRlib(bc);
upstream_modules.push((bc, CString::new(id).unwrap()));
}
@@ -281,14 +279,14 @@ fn fat_lto(
// save and persist everything with the original module.
let mut linker = Linker::new(llmod);
for (bc_decoded, name) in serialized_modules {
let _timer = cgcx.prof.generic_activity("LLVM_fat_lto_link_module");
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_fat_lto_link_module", format!("{:?}", name));
info!("linking {:?}", name);
cgcx.prof.extra_verbose_generic_activity(&format!("ll link {:?}", name)).run(|| {
let data = bc_decoded.data();
linker.add(&data).map_err(|()| {
let msg = format!("failed to load bc of {:?}", name);
write::llvm_err(&diag_handler, &msg)
})
let data = bc_decoded.data();
linker.add(&data).map_err(|()| {
let msg = format!("failed to load bc of {:?}", name);
write::llvm_err(&diag_handler, &msg)
})?;
serialized_bitcode.push(bc_decoded);
}
@@ -577,6 +575,8 @@ pub(crate) fn run_pass_manager(
config: &ModuleConfig,
thin: bool,
) {
let _timer = cgcx.prof.extra_verbose_generic_activity("LLVM_lto_optimize", &module.name[..]);

// Now we have one massive module inside of llmod. Time to run the
// LTO-specific optimization passes that LLVM provides.
//
@@ -634,9 +634,7 @@ pub(crate) fn run_pass_manager(
llvm::LLVMRustAddPass(pm, pass.unwrap());
}

cgcx.prof
.extra_verbose_generic_activity("LTO_passes")
.run(|| llvm::LLVMRunPassManager(pm, module.module_llvm.llmod()));
llvm::LLVMRunPassManager(pm, module.module_llvm.llmod());

llvm::LLVMDisposePassManager(pm);
}
@@ -760,7 +758,9 @@ pub unsafe fn optimize_thin_module(
// Like with "fat" LTO, get some better optimizations if landing pads
// are disabled by removing all landing pads.
if cgcx.no_landing_pads {
let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_remove_landing_pads");
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_thin_lto_remove_landing_pads", thin_module.name());
llvm::LLVMRustMarkAllFunctionsNounwind(llmod);
save_temp_bitcode(&cgcx, &module, "thin-lto-after-nounwind");
}
@@ -774,7 +774,8 @@ pub unsafe fn optimize_thin_module(
// You can find some more comments about these functions in the LLVM
// bindings we've got (currently `PassWrapper.cpp`)
{
let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_rename");
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name());
if !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod) {
let msg = "failed to prepare thin LTO module";
return Err(write::llvm_err(&diag_handler, msg));
@@ -783,7 +784,9 @@ pub unsafe fn optimize_thin_module(
}

{
let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_resolve_weak");
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_thin_lto_resolve_weak", thin_module.name());
if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) {
let msg = "failed to prepare thin LTO module";
return Err(write::llvm_err(&diag_handler, msg));
@@ -792,7 +795,9 @@ pub unsafe fn optimize_thin_module(
}

{
let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_internalize");
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_thin_lto_internalize", thin_module.name());
if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) {
let msg = "failed to prepare thin LTO module";
return Err(write::llvm_err(&diag_handler, msg));
@@ -801,7 +806,8 @@ pub unsafe fn optimize_thin_module(
}

{
let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_import");
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name());
if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod) {
let msg = "failed to prepare thin LTO module";
return Err(write::llvm_err(&diag_handler, msg));
@@ -839,7 +845,9 @@ pub unsafe fn optimize_thin_module(
// so it appears). Hopefully we can remove this once upstream bugs are
// fixed in LLVM.
{
let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_patch_debuginfo");
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_thin_lto_patch_debuginfo", thin_module.name());
llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1);
save_temp_bitcode(cgcx, &module, "thin-lto-after-patch");
}
@@ -850,7 +858,6 @@ pub unsafe fn optimize_thin_module(
// populate a thin-specific pass manager, which presumably LLVM treats a
// little differently.
{
let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_optimize");
info!("running thin lto passes over {}", module.name);
let config = cgcx.config(module.kind);
run_pass_manager(cgcx, &module, config, true);
69 changes: 37 additions & 32 deletions src/librustc_codegen_llvm/back/write.rs
Original file line number Diff line number Diff line change
@@ -310,7 +310,7 @@ pub(crate) unsafe fn optimize(
module: &ModuleCodegen<ModuleLlvm>,
config: &ModuleConfig,
) -> Result<(), FatalError> {
let _timer = cgcx.prof.generic_activity("LLVM_module_optimize");
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &module.name[..]);

let llmod = module.module_llvm.llmod();
let llcx = &*module.module_llvm.llcx;
@@ -424,23 +424,17 @@ pub(crate) unsafe fn optimize(

// Finally, run the actual optimization passes
{
let _timer = cgcx.prof.generic_activity("LLVM_module_optimize_function_passes");
let desc = &format!("llvm function passes [{}]", module_name.unwrap());
let _timer = if config.time_module {
Some(cgcx.prof.extra_verbose_generic_activity(desc))
} else {
None
};
let _timer = cgcx.prof.extra_verbose_generic_activity(
"LLVM_module_optimize_function_passes",
&module.name[..],
);
llvm::LLVMRustRunFunctionPassManager(fpm, llmod);
}
{
let _timer = cgcx.prof.generic_activity("LLVM_module_optimize_module_passes");
let desc = &format!("llvm module passes [{}]", module_name.unwrap());
let _timer = if config.time_module {
Some(cgcx.prof.extra_verbose_generic_activity(desc))
} else {
None
};
let _timer = cgcx.prof.extra_verbose_generic_activity(
"LLVM_module_optimize_module_passes",
&module.name[..],
);
llvm::LLVMRunPassManager(mpm, llmod);
}

@@ -480,7 +474,7 @@ pub(crate) unsafe fn codegen(
module: ModuleCodegen<ModuleLlvm>,
config: &ModuleConfig,
) -> Result<CompiledModule, FatalError> {
let _timer = cgcx.prof.generic_activity("LLVM_module_codegen");
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_codegen", &module.name[..]);
{
let llmod = module.module_llvm.llmod();
let llcx = &*module.module_llvm.llcx;
@@ -533,26 +527,36 @@ pub(crate) unsafe fn codegen(
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);

if write_bc || config.emit_bc_compressed || config.embed_bitcode {
let _timer = cgcx.prof.generic_activity("LLVM_module_codegen_make_bitcode");
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &module.name[..]);
let thin = ThinBuffer::new(llmod);
let data = thin.data();

if write_bc {
let _timer = cgcx.prof.generic_activity("LLVM_module_codegen_emit_bitcode");
let _timer = cgcx.prof.generic_activity_with_arg(
"LLVM_module_codegen_emit_bitcode",
&module.name[..],
);
if let Err(e) = fs::write(&bc_out, data) {
let msg = format!("failed to write bytecode to {}: {}", bc_out.display(), e);
diag_handler.err(&msg);
}
}

if config.embed_bitcode {
let _timer = cgcx.prof.generic_activity("LLVM_module_codegen_embed_bitcode");
let _timer = cgcx.prof.generic_activity_with_arg(
"LLVM_module_codegen_embed_bitcode",
&module.name[..],
);
embed_bitcode(cgcx, llcx, llmod, Some(data));
}

if config.emit_bc_compressed {
let _timer =
cgcx.prof.generic_activity("LLVM_module_codegen_emit_compressed_bitcode");
let _timer = cgcx.prof.generic_activity_with_arg(
"LLVM_module_codegen_emit_compressed_bitcode",
&module.name[..],
);
let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION);
let data = bytecode::encode(&module.name, data);
if let Err(e) = fs::write(&dst, data) {
@@ -565,15 +569,10 @@ pub(crate) unsafe fn codegen(
}

{
let desc = &format!("codegen passes [{}]", module_name.unwrap());
let _timer = if config.time_module {
Some(cgcx.prof.extra_verbose_generic_activity(desc))
} else {
None
};

if config.emit_ir {
let _timer = cgcx.prof.generic_activity("LLVM_module_codegen_emit_ir");
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &module.name[..]);
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
let out_c = path_to_c_string(&out);

@@ -618,7 +617,9 @@ pub(crate) unsafe fn codegen(
}

if config.emit_asm || asm_to_obj {
let _timer = cgcx.prof.generic_activity("LLVM_module_codegen_emit_asm");
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]);
let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);

// We can't use the same module for asm and binary output, because that triggers
@@ -638,7 +639,9 @@ pub(crate) unsafe fn codegen(
}

if write_obj {
let _timer = cgcx.prof.generic_activity("LLVM_module_codegen_emit_obj");
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
with_codegen(tm, llmod, config.no_builtins, |cpm| {
write_output_file(
diag_handler,
@@ -650,7 +653,9 @@ pub(crate) unsafe fn codegen(
)
})?;
} else if asm_to_obj {
let _timer = cgcx.prof.generic_activity("LLVM_module_codegen_asm_to_obj");
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]);
let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
run_assembler(cgcx, diag_handler, &assembly, &obj_out);

2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/back/link.rs
Original file line number Diff line number Diff line change
@@ -1648,7 +1648,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
let name = cratepath.file_name().unwrap().to_str().unwrap();
let name = &name[3..name.len() - 5]; // chop off lib/.rlib

sess.prof.extra_verbose_generic_activity(&format!("altering {}.rlib", name)).run(|| {
sess.prof.generic_activity_with_arg("link_altering_rlib", name).run(|| {
let mut archive = <B as ArchiveBuilder>::new(sess, &dst, Some(cratepath));
archive.update_symbols();

19 changes: 13 additions & 6 deletions src/librustc_codegen_ssa/back/write.rs
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ use rustc::session::Session;
use rustc::ty::TyCtxt;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::profiling::TimingGuard;
use rustc_data_structures::profiling::VerboseTimingGuard;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
@@ -691,11 +692,17 @@ impl<B: WriteBackendMethods> WorkItem<B> {
}
}

fn profiling_event_id(&self) -> &'static str {
fn start_profiling<'a>(&self, cgcx: &'a CodegenContext<B>) -> TimingGuard<'a> {
match *self {
WorkItem::Optimize(_) => "codegen_module_optimize",
WorkItem::CopyPostLtoArtifacts(_) => "codegen_copy_artifacts_from_incr_cache",
WorkItem::LTO(_) => "codegen_module_perform_lto",
WorkItem::Optimize(ref m) => {
cgcx.prof.generic_activity_with_arg("codegen_module_optimize", &m.name[..])
}
WorkItem::CopyPostLtoArtifacts(ref m) => cgcx
.prof
.generic_activity_with_arg("codegen_copy_artifacts_from_incr_cache", &m.name[..]),
WorkItem::LTO(ref m) => {
cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", m.name())
}
}
}
}
@@ -1520,7 +1527,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
llvm_start_time: &mut Option<VerboseTimingGuard<'a>>,
) {
if config.time_module && llvm_start_time.is_none() {
*llvm_start_time = Some(prof.extra_verbose_generic_activity("LLVM_passes"));
*llvm_start_time = Some(prof.extra_verbose_generic_activity("LLVM_passes", "crate"));
}
}
}
@@ -1575,7 +1582,7 @@ fn spawn_work<B: ExtraBackendMethods>(cgcx: CodegenContext<B>, work: WorkItem<B>
// as a diagnostic was already sent off to the main thread - just
// surface that there was an error in this worker.
bomb.result = {
let _prof_timer = cgcx.prof.generic_activity(work.profiling_event_id());
let _prof_timer = work.start_profiling(&cgcx);
Some(execute_work_item(&cgcx, work))
};
});
107 changes: 73 additions & 34 deletions src/librustc_data_structures/profiling.rs
Original file line number Diff line number Diff line change
@@ -83,6 +83,9 @@
use crate::fx::FxHashMap;

use std::borrow::Borrow;
use std::collections::hash_map::Entry;
use std::convert::Into;
use std::error::Error;
use std::fs;
use std::path::Path;
@@ -123,11 +126,14 @@ bitflags::bitflags! {
const INCR_CACHE_LOADS = 1 << 4;

const QUERY_KEYS = 1 << 5;
const FUNCTION_ARGS = 1 << 6;

const DEFAULT = Self::GENERIC_ACTIVITIES.bits |
Self::QUERY_PROVIDERS.bits |
Self::QUERY_BLOCKED.bits |
Self::INCR_CACHE_LOADS.bits;

const ARGS = Self::QUERY_KEYS.bits | Self::FUNCTION_ARGS.bits;
}
}

@@ -142,6 +148,8 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
("query-blocked", EventFilter::QUERY_BLOCKED),
("incr-cache-load", EventFilter::INCR_CACHE_LOADS),
("query-keys", EventFilter::QUERY_KEYS),
("function-args", EventFilter::FUNCTION_ARGS),
("args", EventFilter::ARGS),
];

/// Something that uniquely identifies a query invocation.
@@ -216,43 +224,68 @@ impl SelfProfilerRef {
/// VerboseTimingGuard returned from this call is dropped. In addition to recording
/// a measureme event, "verbose" generic activities also print a timing entry to
/// stdout if the compiler is invoked with -Ztime or -Ztime-passes.
#[inline(always)]
pub fn verbose_generic_activity<'a>(
&'a self,
event_id: &'static str,
event_label: &'static str,
) -> VerboseTimingGuard<'a> {
VerboseTimingGuard::start(
event_id,
self.print_verbose_generic_activities,
self.generic_activity(event_id),
)
let message =
if self.print_verbose_generic_activities { Some(event_label.to_owned()) } else { None };

VerboseTimingGuard::start(message, self.generic_activity(event_label))
}

/// Start profiling a extra verbose generic activity. Profiling continues until the
/// VerboseTimingGuard returned from this call is dropped. In addition to recording
/// a measureme event, "extra verbose" generic activities also print a timing entry to
/// stdout if the compiler is invoked with -Ztime-passes.
#[inline(always)]
pub fn extra_verbose_generic_activity<'a>(
pub fn extra_verbose_generic_activity<'a, A>(
&'a self,
event_id: &'a str,
) -> VerboseTimingGuard<'a> {
// FIXME: This does not yet emit a measureme event
// because callers encode arguments into `event_id`.
VerboseTimingGuard::start(
event_id,
self.print_extra_verbose_generic_activities,
TimingGuard::none(),
)
event_label: &'static str,
event_arg: A,
) -> VerboseTimingGuard<'a>
where
A: Borrow<str> + Into<String>,
{
let message = if self.print_extra_verbose_generic_activities {
Some(format!("{}({})", event_label, event_arg.borrow()))
} else {
None
};

VerboseTimingGuard::start(message, self.generic_activity_with_arg(event_label, event_arg))
}

/// Start profiling a generic activity. Profiling continues until the
/// TimingGuard returned from this call is dropped.
#[inline(always)]
pub fn generic_activity(&self, event_label: &'static str) -> TimingGuard<'_> {
self.exec(EventFilter::GENERIC_ACTIVITIES, |profiler| {
let event_label = profiler.get_or_alloc_cached_string(event_label);
let event_id = EventId::from_label(event_label);
TimingGuard::start(profiler, profiler.generic_activity_event_kind, event_id)
})
}

/// Start profiling a generic activity. Profiling continues until the
/// TimingGuard returned from this call is dropped.
#[inline(always)]
pub fn generic_activity(&self, event_id: &'static str) -> TimingGuard<'_> {
pub fn generic_activity_with_arg<A>(
&self,
event_label: &'static str,
event_arg: A,
) -> TimingGuard<'_>
where
A: Borrow<str> + Into<String>,
{
self.exec(EventFilter::GENERIC_ACTIVITIES, |profiler| {
let event_id = profiler.get_or_alloc_cached_string(event_id);
let event_id = EventId::from_label(event_id);
let builder = EventIdBuilder::new(&profiler.profiler);
let event_label = profiler.get_or_alloc_cached_string(event_label);
let event_id = if profiler.event_filter_mask.contains(EventFilter::FUNCTION_ARGS) {
let event_arg = profiler.get_or_alloc_cached_string(event_arg);
builder.from_label_and_arg(event_label, event_arg)
} else {
builder.from_label(event_label)
};
TimingGuard::start(profiler, profiler.generic_activity_event_kind, event_id)
})
}
@@ -337,7 +370,7 @@ pub struct SelfProfiler {
profiler: Profiler,
event_filter_mask: EventFilter,

string_cache: RwLock<FxHashMap<&'static str, StringId>>,
string_cache: RwLock<FxHashMap<String, StringId>>,

query_event_kind: StringId,
generic_activity_event_kind: StringId,
@@ -419,21 +452,30 @@ impl SelfProfiler {
/// Gets a `StringId` for the given string. This method makes sure that
/// any strings going through it will only be allocated once in the
/// profiling data.
pub fn get_or_alloc_cached_string(&self, s: &'static str) -> StringId {
pub fn get_or_alloc_cached_string<A>(&self, s: A) -> StringId
where
A: Borrow<str> + Into<String>,
{
// Only acquire a read-lock first since we assume that the string is
// already present in the common case.
{
let string_cache = self.string_cache.read();

if let Some(&id) = string_cache.get(s) {
if let Some(&id) = string_cache.get(s.borrow()) {
return id;
}
}

let mut string_cache = self.string_cache.write();
// Check if the string has already been added in the small time window
// between dropping the read lock and acquiring the write lock.
*string_cache.entry(s).or_insert_with(|| self.profiler.alloc_string(s))
match string_cache.entry(s.into()) {
Entry::Occupied(e) => *e.get(),
Entry::Vacant(e) => {
let string_id = self.profiler.alloc_string(&e.key()[..]);
*e.insert(string_id)
}
}
}

pub fn map_query_invocation_id_to_string(&self, from: QueryInvocationId, to: StringId) {
@@ -498,18 +540,13 @@ impl<'a> TimingGuard<'a> {

#[must_use]
pub struct VerboseTimingGuard<'a> {
event_id: &'a str,
start: Option<Instant>,
start_and_message: Option<(Instant, String)>,
_guard: TimingGuard<'a>,
}

impl<'a> VerboseTimingGuard<'a> {
pub fn start(event_id: &'a str, verbose: bool, _guard: TimingGuard<'a>) -> Self {
VerboseTimingGuard {
event_id,
_guard,
start: if unlikely!(verbose) { Some(Instant::now()) } else { None },
}
pub fn start(message: Option<String>, _guard: TimingGuard<'a>) -> Self {
VerboseTimingGuard { _guard, start_and_message: message.map(|msg| (Instant::now(), msg)) }
}

#[inline(always)]
@@ -521,7 +558,9 @@ impl<'a> VerboseTimingGuard<'a> {

impl Drop for VerboseTimingGuard<'_> {
fn drop(&mut self) {
self.start.map(|start| print_time_passes_entry(true, self.event_id, start.elapsed()));
if let Some((start, ref message)) = self.start_and_message {
print_time_passes_entry(true, &message[..], start.elapsed());
}
}
}

2 changes: 1 addition & 1 deletion src/librustc_error_codes/error_codes.rs
Original file line number Diff line number Diff line change
@@ -353,6 +353,7 @@ E0631: include_str!("./error_codes/E0631.md"),
E0633: include_str!("./error_codes/E0633.md"),
E0635: include_str!("./error_codes/E0635.md"),
E0636: include_str!("./error_codes/E0636.md"),
E0637: include_str!("./error_codes/E0637.md"),
E0638: include_str!("./error_codes/E0638.md"),
E0639: include_str!("./error_codes/E0639.md"),
E0641: include_str!("./error_codes/E0641.md"),
@@ -584,7 +585,6 @@ E0746: include_str!("./error_codes/E0746.md"),
E0632, // cannot provide explicit generic arguments when `impl Trait` is
// used in argument position
E0634, // type has conflicting packed representaton hints
E0637, // "'_" is not a valid lifetime bound
E0640, // infer outlives requirements
// E0645, // trait aliases not finished
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
10 changes: 6 additions & 4 deletions src/librustc_error_codes/error_codes/E0275.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
This error occurs when there was a recursive trait requirement that overflowed
before it could be evaluated. Often this means that there is unbounded
recursion in resolving some type bounds.
An evaluation of a trait requirement overflowed.

For example, in the following code:
Erroneous code example:

```compile_fail,E0275
trait Foo {}
@@ -12,6 +10,10 @@ struct Bar<T>(T);
impl<T> Foo for T where Bar<T>: Foo {}
```

This error occurs when there was a recursive trait requirement that overflowed
before it could be evaluated. This often means that there is an unbounded
recursion in resolving some type bounds.

To determine if a `T` is `Foo`, we need to check if `Bar<T>` is `Foo`. However,
to do this check, we need to determine that `Bar<Bar<T>>` is `Foo`. To
determine this, we check if `Bar<Bar<Bar<T>>>` is `Foo`, and so on. This is
9 changes: 5 additions & 4 deletions src/librustc_error_codes/error_codes/E0283.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
This error occurs when the compiler doesn't have enough information
to unambiguously choose an implementation.
An implementation cannot be chosen unambiguously because of lack of information.

For example:
Erroneous code example:

```compile_fail,E0283
trait Generator {
@@ -27,7 +26,9 @@ fn main() {
}
```

To resolve this error use the concrete type:
This error can be solved by adding type annotations that provide the missing
information to the compiler. In this case, the solution is to use a concrete
type:

```
trait Generator {
32 changes: 32 additions & 0 deletions src/librustc_error_codes/error_codes/E0637.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
An underscore `_` character has been used as the identifier for a lifetime.

Erroneous example:
```compile_fail,E0106,E0637
fn longest<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str {
//^^ `'_` is a reserved lifetime name
if str1.len() > str2.len() {
str1
} else {
str2
}
}
```
`'_`, cannot be used as a lifetime identifier because it is a reserved for the
anonymous lifetime. To fix this, use a lowercase letter such as 'a, or a series
of lowercase letters such as `'foo`. For more information, see [the
book][bk-no]. For more information on using the anonymous lifetime in rust
nightly, see [the nightly book][bk-al].

Corrected example:
```
fn longest<'a>(str1: &'a str, str2: &'a str) -> &'a str {
if str1.len() > str2.len() {
str1
} else {
str2
}
}
```

[bk-no]: https://doc.rust-lang.org/book/appendix-02-operators.html#non-operator-symbols
[bk-al]: https://doc.rust-lang.org/nightly/edition-guide/rust-2018/ownership-and-lifetimes/the-anonymous-lifetime.html
6 changes: 2 additions & 4 deletions src/librustc_lint/early.rs
Original file line number Diff line number Diff line change
@@ -342,10 +342,8 @@ pub fn check_ast_crate<T: EarlyLintPass>(
}
} else {
for pass in &mut passes {
buffered = sess
.prof
.extra_verbose_generic_activity(&format!("running lint: {}", pass.name()))
.run(|| {
buffered =
sess.prof.extra_verbose_generic_activity("run_lint", pass.name()).run(|| {
early_lint_crate(
sess,
lint_store,
21 changes: 7 additions & 14 deletions src/librustc_lint/late.rs
Original file line number Diff line number Diff line change
@@ -441,27 +441,20 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b
late_lint_pass_crate(tcx, builtin_lints);
} else {
for pass in &mut passes {
tcx.sess
.prof
.extra_verbose_generic_activity(&format!("running late lint: {}", pass.name()))
.run(|| {
late_lint_pass_crate(tcx, LateLintPassObjects { lints: slice::from_mut(pass) });
});
tcx.sess.prof.extra_verbose_generic_activity("run_late_lint", pass.name()).run(|| {
late_lint_pass_crate(tcx, LateLintPassObjects { lints: slice::from_mut(pass) });
});
}

let mut passes: Vec<_> =
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)()).collect();

for pass in &mut passes {
tcx.sess
.prof
.extra_verbose_generic_activity(&format!(
"running late module lint: {}",
pass.name()
))
.run(|| {
tcx.sess.prof.extra_verbose_generic_activity("run_late_module_lint", pass.name()).run(
|| {
late_lint_pass_crate(tcx, LateLintPassObjects { lints: slice::from_mut(pass) });
});
},
);
}
}
}
5 changes: 4 additions & 1 deletion src/librustc_parse/parser/ty.rs
Original file line number Diff line number Diff line change
@@ -214,7 +214,10 @@ impl<'a> Parser<'a> {
let path = match bounds.remove(0) {
GenericBound::Trait(pt, ..) => pt.trait_ref.path,
GenericBound::Outlives(..) => {
self.span_bug(ty.span, "unexpected lifetime bound")
return Err(self.struct_span_err(
ty.span,
"expected trait bound, not lifetime bound",
));
}
};
self.parse_remaining_bounds(Vec::new(), path, lo, true)
Original file line number Diff line number Diff line change
@@ -38,3 +38,4 @@ LL | #![feature(const_generics)]

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0637`.
55 changes: 55 additions & 0 deletions src/test/ui/consts/ascii_ctype.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// run-pass

#![feature(const_ascii_ctype_on_intrinsics)]

macro_rules! suite {
( $( $fn:ident => [$a:ident, $A:ident, $nine:ident, $dot:ident, $space:ident]; )* ) => {
$(
mod $fn {
const CHAR_A_LOWER: bool = 'a'.$fn();
const CHAR_A_UPPER: bool = 'A'.$fn();
const CHAR_NINE: bool = '9'.$fn();
const CHAR_DOT: bool = '.'.$fn();
const CHAR_SPACE: bool = ' '.$fn();

const U8_A_LOWER: bool = b'a'.$fn();
const U8_A_UPPER: bool = b'A'.$fn();
const U8_NINE: bool = b'9'.$fn();
const U8_DOT: bool = b'.'.$fn();
const U8_SPACE: bool = b' '.$fn();

pub fn run() {
assert_eq!(CHAR_A_LOWER, $a);
assert_eq!(CHAR_A_UPPER, $A);
assert_eq!(CHAR_NINE, $nine);
assert_eq!(CHAR_DOT, $dot);
assert_eq!(CHAR_SPACE, $space);

assert_eq!(U8_A_LOWER, $a);
assert_eq!(U8_A_UPPER, $A);
assert_eq!(U8_NINE, $nine);
assert_eq!(U8_DOT, $dot);
assert_eq!(U8_SPACE, $space);
}
}
)*

fn main() {
$( $fn::run(); )*
}
}
}

suite! {
// 'a' 'A' '9' '.' ' '
is_ascii_alphabetic => [true, true, false, false, false];
is_ascii_uppercase => [false, true, false, false, false];
is_ascii_lowercase => [true, false, false, false, false];
is_ascii_alphanumeric => [true, true, true, false, false];
is_ascii_digit => [false, false, true, false, false];
is_ascii_hexdigit => [true, true, true, false, false];
is_ascii_punctuation => [false, false, false, true, false];
is_ascii_graphic => [true, true, true, true, false];
is_ascii_whitespace => [false, false, false, false, true];
is_ascii_control => [false, false, false, false, false];
}
1 change: 1 addition & 0 deletions src/test/ui/error-codes/E0637.stderr
Original file line number Diff line number Diff line change
@@ -18,3 +18,4 @@ LL | impl<'a: '_> Bar<'a> {

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0637`.
Original file line number Diff line number Diff line change
@@ -18,4 +18,5 @@ LL | fn bar<'b, L: X<&'b Nested<i32>>>(){}

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0106`.
Some errors have detailed explanations: E0106, E0637.
For more information about an error, try `rustc --explain E0106`.
4 changes: 4 additions & 0 deletions src/test/ui/parser/issue-68890.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
enum e{A((?'a a+?+l))}
//~^ ERROR `?` may only modify trait bounds, not lifetime bounds
//~| ERROR expected one of `)`, `+`, or `,`
//~| ERROR expected trait bound, not lifetime bound
20 changes: 20 additions & 0 deletions src/test/ui/parser/issue-68890.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: `?` may only modify trait bounds, not lifetime bounds
--> $DIR/issue-68890.rs:1:11
|
LL | enum e{A((?'a a+?+l))}
| ^

error: expected one of `)`, `+`, or `,`, found `a`
--> $DIR/issue-68890.rs:1:15
|
LL | enum e{A((?'a a+?+l))}
| ^ expected one of `)`, `+`, or `,`

error: expected trait bound, not lifetime bound
--> $DIR/issue-68890.rs:1:11
|
LL | enum e{A((?'a a+?+l))}
| ^^^

error: aborting due to 3 previous errors

1 change: 1 addition & 0 deletions src/test/ui/underscore-lifetime/in-binder.stderr
Original file line number Diff line number Diff line change
@@ -36,3 +36,4 @@ LL | fn foo<'_>() {

error: aborting due to 6 previous errors

For more information about this error, try `rustc --explain E0637`.
Original file line number Diff line number Diff line change
@@ -38,4 +38,5 @@ LL | fn foo2<'a>(_: &'a u8, y: &'a u8) -> &'a u8 { y }

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0106`.
Some errors have detailed explanations: E0106, E0637.
For more information about an error, try `rustc --explain E0106`.
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | impl<'b: '_> Foo<'b> for i32 {}

error: aborting due to previous error

For more information about this error, try `rustc --explain E0637`.
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | T: WithType<&u32>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0637`.
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | T: WithType<&u32>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0637`.
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | T: WithRegion<'_>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0637`.
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | T: WithRegion<'_>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0637`.
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | T: WithType<&u32>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0637`.
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | T: WithType<&u32>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0637`.
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | T: WithRegion<'_>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0637`.
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | T: WithRegion<'_>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0637`.
1 change: 1 addition & 0 deletions src/test/ui/underscore-lifetime/where-clauses.stderr
Original file line number Diff line number Diff line change
@@ -12,3 +12,4 @@ LL | impl<T: '_> Foo<'static> for Vec<T> {}

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0637`.