mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #95414 - Dylan-DPC:rollup-9hbshd0, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #93787 (parallel_compiler: hide dependencies behind feature) - #95318 (diagnostics: correct generic bounds with doubled colon) - #95328 (Fix yet another Box<T, A> ICE) - #95397 (Link to std::io's platform-specific behavior disclaimer) - #95407 (Inline u8::is_utf8_char_boundary) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ee915c34e2
@ -19,3 +19,4 @@ features = ['unprefixed_malloc_on_supported_platforms']
|
||||
jemalloc = ['tikv-jemalloc-sys']
|
||||
llvm = ['rustc_driver/llvm']
|
||||
max_level_info = ['rustc_driver/max_level_info']
|
||||
rustc_use_parallel_compiler = ['rustc_driver/rustc_use_parallel_compiler']
|
||||
|
@ -14,6 +14,8 @@ use crate::{CachedModuleCodegen, CompiledModule, CrateInfo, MemFlags, ModuleCode
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
use rustc_data_structures::sync::{par_iter, ParallelIterator};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
@ -622,34 +624,34 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
||||
// This likely is a temporary measure. Once we don't have to support the
|
||||
// non-parallel compiler anymore, we can compile CGUs end-to-end in
|
||||
// parallel and get rid of the complicated scheduling logic.
|
||||
#[cfg(parallel_compiler)]
|
||||
let pre_compile_cgus = |cgu_reuse: &[CguReuse]| {
|
||||
if cfg!(parallel_compiler) {
|
||||
tcx.sess.time("compile_first_CGU_batch", || {
|
||||
// Try to find one CGU to compile per thread.
|
||||
let cgus: Vec<_> = cgu_reuse
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, reuse)| reuse == &CguReuse::No)
|
||||
.take(tcx.sess.threads())
|
||||
.collect();
|
||||
tcx.sess.time("compile_first_CGU_batch", || {
|
||||
// Try to find one CGU to compile per thread.
|
||||
let cgus: Vec<_> = cgu_reuse
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, reuse)| reuse == &CguReuse::No)
|
||||
.take(tcx.sess.threads())
|
||||
.collect();
|
||||
|
||||
// Compile the found CGUs in parallel.
|
||||
let start_time = Instant::now();
|
||||
// Compile the found CGUs in parallel.
|
||||
let start_time = Instant::now();
|
||||
|
||||
let pre_compiled_cgus = par_iter(cgus)
|
||||
.map(|(i, _)| {
|
||||
let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
|
||||
(i, module)
|
||||
})
|
||||
.collect();
|
||||
let pre_compiled_cgus = par_iter(cgus)
|
||||
.map(|(i, _)| {
|
||||
let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
|
||||
(i, module)
|
||||
})
|
||||
.collect();
|
||||
|
||||
(pre_compiled_cgus, start_time.elapsed())
|
||||
})
|
||||
} else {
|
||||
(FxHashMap::default(), Duration::new(0, 0))
|
||||
}
|
||||
(pre_compiled_cgus, start_time.elapsed())
|
||||
})
|
||||
};
|
||||
|
||||
#[cfg(not(parallel_compiler))]
|
||||
let pre_compile_cgus = |_: &[CguReuse]| (FxHashMap::default(), Duration::new(0, 0));
|
||||
|
||||
let mut cgu_reuse = Vec::new();
|
||||
let mut pre_compiled_cgus: Option<FxHashMap<usize, _>> = None;
|
||||
let mut total_codegen_time = Duration::new(0, 0);
|
||||
|
@ -441,11 +441,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
|
||||
{
|
||||
base = elem.0 + 1;
|
||||
self.codegen_consume(
|
||||
let cg_base = self.codegen_consume(
|
||||
bx,
|
||||
mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
|
||||
)
|
||||
.deref(bx.cx())
|
||||
);
|
||||
|
||||
// a box with a non-zst allocator should not be directly dereferenced
|
||||
if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
|
||||
let ptr = cg_base.extract_field(bx, 0).extract_field(bx, 0);
|
||||
|
||||
ptr.deref(bx.cx())
|
||||
} else {
|
||||
cg_base.deref(bx.cx())
|
||||
}
|
||||
} else {
|
||||
bug!("using operand local {:?} as place", place_ref);
|
||||
}
|
||||
@ -454,10 +462,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
for elem in place_ref.projection[base..].iter() {
|
||||
cg_base = match elem.clone() {
|
||||
mir::ProjectionElem::Deref => {
|
||||
// custom allocators can change box's abi, making it unable to be derefed directly
|
||||
if cg_base.layout.ty.is_box()
|
||||
&& matches!(cg_base.layout.abi, Abi::Aggregate { .. } | Abi::Uninhabited)
|
||||
{
|
||||
// a box with a non-zst allocator should not be directly dereferenced
|
||||
if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
|
||||
let ptr = cg_base.project_field(bx, 0).project_field(bx, 0);
|
||||
|
||||
bx.load_operand(ptr).deref(bx.cx())
|
||||
|
@ -9,7 +9,7 @@ doctest = false
|
||||
[dependencies]
|
||||
arrayvec = { version = "0.7", default-features = false }
|
||||
ena = "0.14"
|
||||
indexmap = { version = "1.8.0", features = ["rustc-rayon"] }
|
||||
indexmap = { version = "1.8.0" }
|
||||
tracing = "0.1"
|
||||
jobserver_crate = { version = "0.1.13", package = "jobserver" }
|
||||
rustc_serialize = { path = "../rustc_serialize" }
|
||||
@ -17,8 +17,8 @@ rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_graphviz = { path = "../rustc_graphviz" }
|
||||
cfg-if = "0.1.2"
|
||||
stable_deref_trait = "1.0.0"
|
||||
rayon = { version = "0.3.2", package = "rustc-rayon" }
|
||||
rayon-core = { version = "0.3.2", package = "rustc-rayon-core" }
|
||||
rayon = { version = "0.3.2", package = "rustc-rayon", optional = true }
|
||||
rayon-core = { version = "0.3.2", package = "rustc-rayon-core", optional = true }
|
||||
rustc-hash = "1.1.0"
|
||||
smallvec = { version = "1.6.1", features = ["const_generics", "union", "may_dangle"] }
|
||||
rustc_index = { path = "../rustc_index", package = "rustc_index" }
|
||||
@ -36,3 +36,6 @@ winapi = { version = "0.3", features = ["fileapi", "psapi", "winerror"] }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
memmap2 = "0.2.1"
|
||||
|
||||
[features]
|
||||
rustc_use_parallel_compiler = ["indexmap/rustc-rayon", "rayon", "rayon-core"]
|
||||
|
@ -39,3 +39,5 @@ winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"]
|
||||
[features]
|
||||
llvm = ['rustc_interface/llvm']
|
||||
max_level_info = ['rustc_log/max_level_info']
|
||||
rustc_use_parallel_compiler = ['rustc_data_structures/rustc_use_parallel_compiler', 'rustc_interface/rustc_use_parallel_compiler',
|
||||
'rustc_middle/rustc_use_parallel_compiler']
|
||||
|
@ -10,8 +10,8 @@ doctest = false
|
||||
libc = "0.2"
|
||||
libloading = "0.7.1"
|
||||
tracing = "0.1"
|
||||
rustc-rayon-core = "0.3.2"
|
||||
rayon = { version = "0.3.2", package = "rustc-rayon" }
|
||||
rustc-rayon-core = { version = "0.3.2", optional = true }
|
||||
rayon = { version = "0.3.2", package = "rustc-rayon", optional = true }
|
||||
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_attr = { path = "../rustc_attr" }
|
||||
@ -57,3 +57,4 @@ rustc_target = { path = "../rustc_target" }
|
||||
|
||||
[features]
|
||||
llvm = ['rustc_codegen_llvm']
|
||||
rustc_use_parallel_compiler = ['rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler']
|
||||
|
@ -12,8 +12,8 @@ bitflags = "1.2.1"
|
||||
either = "1.5.0"
|
||||
gsgdt = "0.1.2"
|
||||
tracing = "0.1"
|
||||
rustc-rayon = "0.3.2"
|
||||
rustc-rayon-core = "0.3.2"
|
||||
rustc-rayon = { version = "0.3.2", optional = true }
|
||||
rustc-rayon-core = { version = "0.3.2", optional = true }
|
||||
polonius-engine = "0.13.0"
|
||||
rustc_apfloat = { path = "../rustc_apfloat" }
|
||||
rustc_attr = { path = "../rustc_attr" }
|
||||
@ -35,3 +35,6 @@ rustc_session = { path = "../rustc_session" }
|
||||
rustc_type_ir = { path = "../rustc_type_ir" }
|
||||
rand = "0.8.4"
|
||||
rand_xoshiro = "0.6.0"
|
||||
|
||||
[features]
|
||||
rustc_use_parallel_compiler = ["rustc-rayon", "rustc-rayon-core"]
|
||||
|
@ -2369,6 +2369,34 @@ impl<'a> Parser<'a> {
|
||||
Err(err)
|
||||
}
|
||||
|
||||
crate fn maybe_recover_bounds_doubled_colon(&mut self, ty: &Ty) -> PResult<'a, ()> {
|
||||
let TyKind::Path(qself, path) = &ty.kind else { return Ok(()) };
|
||||
let qself_position = qself.as_ref().map(|qself| qself.position);
|
||||
for (i, segments) in path.segments.windows(2).enumerate() {
|
||||
if qself_position.map(|pos| i < pos).unwrap_or(false) {
|
||||
continue;
|
||||
}
|
||||
if let [a, b] = segments {
|
||||
let (a_span, b_span) = (a.span(), b.span());
|
||||
let between_span = a_span.shrink_to_hi().to(b_span.shrink_to_lo());
|
||||
if self.span_to_snippet(between_span).as_ref().map(|a| &a[..]) == Ok(":: ") {
|
||||
let mut err = self.struct_span_err(
|
||||
path.span.shrink_to_hi(),
|
||||
"expected `:` followed by trait or lifetime",
|
||||
);
|
||||
err.span_suggestion(
|
||||
between_span,
|
||||
"use single colon",
|
||||
": ".to_owned(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parse and throw away a parenthesized comma separated
|
||||
/// sequence of patterns until `)` is reached.
|
||||
fn skip_pat_list(&mut self) -> PResult<'a, ()> {
|
||||
|
@ -312,6 +312,7 @@ impl<'a> Parser<'a> {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
}))
|
||||
} else {
|
||||
self.maybe_recover_bounds_doubled_colon(&ty)?;
|
||||
self.unexpected()
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
measureme = "10.0.0"
|
||||
rustc-rayon-core = "0.3.2"
|
||||
rustc-rayon-core = { version = "0.3.2", optional = true }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
@ -20,3 +20,6 @@ rustc_query_system = { path = "../rustc_query_system" }
|
||||
rustc_serialize = { path = "../rustc_serialize" }
|
||||
rustc_session = { path = "../rustc_session" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
|
||||
[features]
|
||||
rustc_use_parallel_compiler = ["rustc-rayon-core", "rustc_query_system/rustc_use_parallel_compiler"]
|
||||
|
@ -9,7 +9,7 @@ doctest = false
|
||||
[dependencies]
|
||||
rustc_arena = { path = "../rustc_arena" }
|
||||
tracing = "0.1"
|
||||
rustc-rayon-core = "0.3.2"
|
||||
rustc-rayon-core = { version = "0.3.2", optional = true }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
@ -23,3 +23,6 @@ rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
parking_lot = "0.11"
|
||||
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
|
||||
|
||||
[features]
|
||||
rustc_use_parallel_compiler = ["rustc-rayon-core"]
|
||||
|
@ -809,6 +809,7 @@ impl u8 {
|
||||
ascii::escape_default(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) const fn is_utf8_char_boundary(self) -> bool {
|
||||
// This is bit magic equivalent to: b < 128 || b >= 192
|
||||
(self as i8) >= -0x40
|
||||
|
@ -25,9 +25,11 @@ use crate::sys::os as os_imp;
|
||||
///
|
||||
/// # Platform-specific behavior
|
||||
///
|
||||
/// This function currently corresponds to the `getcwd` function on Unix
|
||||
/// This function [currently] corresponds to the `getcwd` function on Unix
|
||||
/// and the `GetCurrentDirectoryW` function on Windows.
|
||||
///
|
||||
/// [currently]: crate::io#platform-specific-behavior
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an [`Err`] if the current working directory value is invalid.
|
||||
@ -56,11 +58,13 @@ pub fn current_dir() -> io::Result<PathBuf> {
|
||||
///
|
||||
/// # Platform-specific behavior
|
||||
///
|
||||
/// This function currently corresponds to the `chdir` function on Unix
|
||||
/// This function [currently] corresponds to the `chdir` function on Unix
|
||||
/// and the `SetCurrentDirectoryW` function on Windows.
|
||||
///
|
||||
/// Returns an [`Err`] if the operation fails.
|
||||
///
|
||||
/// [currently]: crate::io#platform-specific-behavior
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
@ -101,7 +101,9 @@ pub use core::time::FromFloatSecsError;
|
||||
/// ```
|
||||
///
|
||||
/// # Underlying System calls
|
||||
/// Currently, the following system calls are being used to get the current time using `now()`:
|
||||
///
|
||||
/// The following system calls are [currently] being used by `now()` to find out
|
||||
/// the current time:
|
||||
///
|
||||
/// | Platform | System call |
|
||||
/// |-----------|----------------------------------------------------------------------|
|
||||
@ -113,6 +115,7 @@ pub use core::time::FromFloatSecsError;
|
||||
/// | WASI | [__wasi_clock_time_get (Monotonic Clock)] |
|
||||
/// | Windows | [QueryPerformanceCounter] |
|
||||
///
|
||||
/// [currently]: crate::io#platform-specific-behavior
|
||||
/// [QueryPerformanceCounter]: https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
|
||||
/// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time
|
||||
/// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode
|
||||
@ -203,7 +206,8 @@ pub struct Instant(time::Instant);
|
||||
/// For example, on Windows the time is represented in 100 nanosecond intervals whereas Linux
|
||||
/// can represent nanosecond intervals.
|
||||
///
|
||||
/// Currently, the following system calls are being used to get the current time using `now()`:
|
||||
/// The following system calls are [currently] being used by `now()` to find out
|
||||
/// the current time:
|
||||
///
|
||||
/// | Platform | System call |
|
||||
/// |-----------|----------------------------------------------------------------------|
|
||||
@ -215,6 +219,7 @@ pub struct Instant(time::Instant);
|
||||
/// | WASI | [__wasi_clock_time_get (Realtime Clock)] |
|
||||
/// | Windows | [GetSystemTimePreciseAsFileTime] / [GetSystemTimeAsFileTime] |
|
||||
///
|
||||
/// [currently]: crate::io#platform-specific-behavior
|
||||
/// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time
|
||||
/// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode
|
||||
/// [gettimeofday]: https://man7.org/linux/man-pages/man2/gettimeofday.2.html
|
||||
|
@ -689,6 +689,8 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS
|
||||
}
|
||||
|
||||
if builder.config.rustc_parallel {
|
||||
// keep in sync with `bootstrap/lib.rs:Build::rustc_features`
|
||||
// `cfg` option for rustc, `features` option for cargo, for conditional compilation
|
||||
cargo.rustflag("--cfg=parallel_compiler");
|
||||
cargo.rustdocflag("--cfg=parallel_compiler");
|
||||
}
|
||||
|
@ -729,12 +729,16 @@ impl Build {
|
||||
|
||||
/// Gets the space-separated set of activated features for the compiler.
|
||||
fn rustc_features(&self, kind: Kind) -> String {
|
||||
let mut features = String::new();
|
||||
let mut features = vec![];
|
||||
if self.config.jemalloc {
|
||||
features.push_str("jemalloc");
|
||||
features.push("jemalloc");
|
||||
}
|
||||
if self.config.llvm_enabled() || kind == Kind::Check {
|
||||
features.push_str(" llvm");
|
||||
features.push("llvm");
|
||||
}
|
||||
// keep in sync with `bootstrap/compile.rs:rustc_cargo_env`
|
||||
if self.config.rustc_parallel {
|
||||
features.push("rustc_use_parallel_compiler");
|
||||
}
|
||||
|
||||
// If debug logging is on, then we want the default for tracing:
|
||||
@ -743,10 +747,10 @@ impl Build {
|
||||
// if its unset, if debug_assertions is on, then debug_logging will also be on
|
||||
// as well as tracing *ignoring* this feature when debug_assertions is on
|
||||
if !self.config.rust_debug_logging {
|
||||
features.push_str(" max_level_info");
|
||||
features.push("max_level_info");
|
||||
}
|
||||
|
||||
features
|
||||
features.join(" ")
|
||||
}
|
||||
|
||||
/// Component directory that Cargo will produce output into (e.g.
|
||||
|
22
src/test/ui/box/issue-95036.rs
Normal file
22
src/test/ui/box/issue-95036.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// compile-flags: -O
|
||||
// build-pass
|
||||
|
||||
#![feature(allocator_api, bench_black_box)]
|
||||
|
||||
#[inline(never)]
|
||||
pub fn by_ref(node: &mut Box<[u8; 1], &std::alloc::Global>) {
|
||||
node[0] = 9u8;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let mut node = Box::new_in([5u8], &std::alloc::Global);
|
||||
node[0] = 7u8;
|
||||
|
||||
std::hint::black_box(node);
|
||||
|
||||
let mut node = Box::new_in([5u8], &std::alloc::Global);
|
||||
|
||||
by_ref(&mut node);
|
||||
|
||||
std::hint::black_box(node);
|
||||
}
|
11
src/test/ui/generics/issue-95208-ignore-qself.fixed
Normal file
11
src/test/ui/generics/issue-95208-ignore-qself.fixed
Normal file
@ -0,0 +1,11 @@
|
||||
// run-rustfix
|
||||
|
||||
#[allow(unused)]
|
||||
struct Struct<T>(T);
|
||||
|
||||
impl<T: Iterator> Struct<T> where <T as std:: iter::Iterator>::Item: std::fmt::Display {
|
||||
//~^ ERROR expected `:` followed by trait or lifetime
|
||||
//~| HELP use single colon
|
||||
}
|
||||
|
||||
fn main() {}
|
11
src/test/ui/generics/issue-95208-ignore-qself.rs
Normal file
11
src/test/ui/generics/issue-95208-ignore-qself.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// run-rustfix
|
||||
|
||||
#[allow(unused)]
|
||||
struct Struct<T>(T);
|
||||
|
||||
impl<T: Iterator> Struct<T> where <T as std:: iter::Iterator>::Item:: std::fmt::Display {
|
||||
//~^ ERROR expected `:` followed by trait or lifetime
|
||||
//~| HELP use single colon
|
||||
}
|
||||
|
||||
fn main() {}
|
10
src/test/ui/generics/issue-95208-ignore-qself.stderr
Normal file
10
src/test/ui/generics/issue-95208-ignore-qself.stderr
Normal file
@ -0,0 +1,10 @@
|
||||
error: expected `:` followed by trait or lifetime
|
||||
--> $DIR/issue-95208-ignore-qself.rs:6:88
|
||||
|
|
||||
LL | impl<T: Iterator> Struct<T> where <T as std:: iter::Iterator>::Item:: std::fmt::Display {
|
||||
| --- ^
|
||||
| |
|
||||
| help: use single colon: `:`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
11
src/test/ui/generics/issue-95208.fixed
Normal file
11
src/test/ui/generics/issue-95208.fixed
Normal file
@ -0,0 +1,11 @@
|
||||
// run-rustfix
|
||||
|
||||
#[allow(unused)]
|
||||
struct Struct<T>(T);
|
||||
|
||||
impl<T> Struct<T> where T: std::fmt::Display {
|
||||
//~^ ERROR expected `:` followed by trait or lifetime
|
||||
//~| HELP use single colon
|
||||
}
|
||||
|
||||
fn main() {}
|
11
src/test/ui/generics/issue-95208.rs
Normal file
11
src/test/ui/generics/issue-95208.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// run-rustfix
|
||||
|
||||
#[allow(unused)]
|
||||
struct Struct<T>(T);
|
||||
|
||||
impl<T> Struct<T> where T:: std::fmt::Display {
|
||||
//~^ ERROR expected `:` followed by trait or lifetime
|
||||
//~| HELP use single colon
|
||||
}
|
||||
|
||||
fn main() {}
|
10
src/test/ui/generics/issue-95208.stderr
Normal file
10
src/test/ui/generics/issue-95208.stderr
Normal file
@ -0,0 +1,10 @@
|
||||
error: expected `:` followed by trait or lifetime
|
||||
--> $DIR/issue-95208.rs:6:46
|
||||
|
|
||||
LL | impl<T> Struct<T> where T:: std::fmt::Display {
|
||||
| --- ^
|
||||
| |
|
||||
| help: use single colon: `:`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user