Auto merge of #103322 - matthiaskrgr:rollup-m9zgpft, r=matthiaskrgr

Rollup of 9 pull requests

Successful merges:

 - #103221 (Fix `SelfVisitor::is_self_ty` ICE)
 - #103230 (Clarify startup)
 - #103281 (Adjust `transmute{,_copy}` to be clearer about which of `T` and `U` is input vs output)
 - #103288 (Fixed docs typo in `library/std/src/time.rs`)
 - #103296 (+/- shortcut now only expand/collapse, not both)
 - #103297 (fix typo)
 - #103313 (Don't label `src/test` tests as `A-testsuite`)
 - #103315 (interpret: remove an incorrect assertion)
 - #103319 (Improve "`~const` is not allowed here" message)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2022-10-20 21:08:28 +00:00
22 changed files with 235 additions and 130 deletions
+43 -20
View File
@@ -38,6 +38,13 @@ enum SelfSemantic {
No,
}
/// What is the context that prevents using `~const`?
enum DisallowTildeConstContext<'a> {
TraitObject,
ImplTrait,
Fn(FnKind<'a>),
}
struct AstValidator<'a> {
session: &'a Session,
@@ -56,7 +63,7 @@ struct AstValidator<'a> {
/// e.g., `impl Iterator<Item = impl Debug>`.
outer_impl_trait: Option<Span>,
is_tilde_const_allowed: bool,
disallow_tilde_const: Option<DisallowTildeConstContext<'a>>,
/// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
/// or `Foo::Bar<impl Trait>`
@@ -93,18 +100,26 @@ impl<'a> AstValidator<'a> {
self.is_impl_trait_banned = old;
}
fn with_tilde_const(&mut self, allowed: bool, f: impl FnOnce(&mut Self)) {
let old = mem::replace(&mut self.is_tilde_const_allowed, allowed);
fn with_tilde_const(
&mut self,
disallowed: Option<DisallowTildeConstContext<'a>>,
f: impl FnOnce(&mut Self),
) {
let old = mem::replace(&mut self.disallow_tilde_const, disallowed);
f(self);
self.is_tilde_const_allowed = old;
self.disallow_tilde_const = old;
}
fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
self.with_tilde_const(true, f)
self.with_tilde_const(None, f)
}
fn with_banned_tilde_const(&mut self, f: impl FnOnce(&mut Self)) {
self.with_tilde_const(false, f)
fn with_banned_tilde_const(
&mut self,
ctx: DisallowTildeConstContext<'a>,
f: impl FnOnce(&mut Self),
) {
self.with_tilde_const(Some(ctx), f)
}
fn with_let_management(
@@ -172,7 +187,7 @@ impl<'a> AstValidator<'a> {
fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
let old = mem::replace(&mut self.outer_impl_trait, outer);
if outer.is_some() {
self.with_banned_tilde_const(f);
self.with_banned_tilde_const(DisallowTildeConstContext::ImplTrait, f);
} else {
f(self);
}
@@ -197,7 +212,10 @@ impl<'a> AstValidator<'a> {
TyKind::ImplTrait(..) => {
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
}
TyKind::TraitObject(..) => self.with_banned_tilde_const(|this| visit::walk_ty(this, t)),
TyKind::TraitObject(..) => self
.with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| {
visit::walk_ty(this, t)
}),
TyKind::Path(ref qself, ref path) => {
// We allow these:
// - `Option<impl Trait>`
@@ -1411,13 +1429,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
);
err.emit();
}
(_, TraitBoundModifier::MaybeConst) => {
if !self.is_tilde_const_allowed {
self.err_handler()
.struct_span_err(bound.span(), "`~const` is not allowed here")
.note("only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions")
.emit();
}
(_, TraitBoundModifier::MaybeConst) if let Some(reason) = &self.disallow_tilde_const => {
let mut err = self.err_handler().struct_span_err(bound.span(), "`~const` is not allowed here");
match reason {
DisallowTildeConstContext::TraitObject => err.note("trait objects cannot have `~const` trait bounds"),
DisallowTildeConstContext::ImplTrait => err.note("`impl Trait`s cannot have `~const` trait bounds"),
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => err.note("closures cannot have `~const` trait bounds"),
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => err.span_note(ident.span, "this function is not `const`, so it cannot have `~const` trait bounds"),
};
err.emit();
}
(_, TraitBoundModifier::MaybeConstMaybe) => {
self.err_handler()
@@ -1523,10 +1543,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
});
}
let tilde_const_allowed = matches!(fk.header(), Some(FnHeader { .. }))
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
let tilde_const_allowed =
matches!(fk.header(), Some(FnHeader { constness: ast::Const::Yes(_), .. }))
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
self.with_tilde_const(tilde_const_allowed, |this| visit::walk_fn(this, fk));
let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
}
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
@@ -1770,7 +1793,7 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
in_const_trait_impl: false,
has_proc_macro_decls: false,
outer_impl_trait: None,
is_tilde_const_allowed: false,
disallow_tilde_const: None,
is_impl_trait_banned: false,
is_assoc_ty_bound_banned: false,
forbidden_let_reason: Some(ForbiddenLetReason::GenericForbidden),
@@ -35,7 +35,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert_eq!(discr.layout.ty, switch_ty);
// Branch to the `otherwise` case by default, if no match is found.
assert!(!targets.iter().is_empty());
let mut target_block = targets.otherwise();
for (const_int, target) in targets.iter() {
+1
View File
@@ -190,6 +190,7 @@ impl<'a, 'b> RunCompiler<'a, 'b> {
run_compiler(self.at_args, self.callbacks, self.file_loader, self.make_codegen_backend)
}
}
fn run_compiler(
at_args: &[String],
callbacks: &mut (dyn Callbacks + Send),
+4 -1
View File
@@ -25,7 +25,10 @@ use std::result;
pub type Result<T> = result::Result<T, ErrorGuaranteed>;
/// Represents a compiler session.
/// Represents a compiler session. Note that every `Compiler` contains a
/// `Session`, but `Compiler` also contains some things that cannot be in
/// `Session`, due to `Session` being in a crate that has many fewer
/// dependencies than this crate.
///
/// Can be used to run `rustc_interface` queries.
/// Created by passing [`Config`] to [`run_compiler`].
+45 -44
View File
@@ -3,14 +3,8 @@ use libloading::Library;
use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
#[cfg(parallel_compiler)]
use rustc_data_structures::jobserver;
use rustc_errors::registry::Registry;
#[cfg(parallel_compiler)]
use rustc_middle::ty::tls;
use rustc_parse::validate_attr;
#[cfg(parallel_compiler)]
use rustc_query_impl::{QueryContext, QueryCtxt};
use rustc_session as session;
use rustc_session::config::CheckCfg;
use rustc_session::config::{self, CrateType};
@@ -25,8 +19,6 @@ use rustc_span::symbol::{sym, Symbol};
use std::env;
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::mem;
#[cfg(not(parallel_compiler))]
use std::panic;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::OnceLock;
@@ -135,13 +127,20 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
_threads: usize,
f: F,
) -> R {
// The thread pool is a single thread in the non-parallel compiler.
thread::scope(|s| {
let mut builder = thread::Builder::new().name("rustc".to_string());
if let Some(size) = get_stack_size() {
builder = builder.stack_size(size);
}
// The "thread pool" is a single spawned thread in the non-parallel
// compiler. We run on a spawned thread instead of the main thread (a) to
// provide control over the stack size, and (b) to increase similarity with
// the parallel compiler, in particular to ensure there is no accidental
// sharing of data between the main thread and the compilation thread
// (which might cause problems for the parallel compiler).
let mut builder = thread::Builder::new().name("rustc".to_string());
if let Some(size) = get_stack_size() {
builder = builder.stack_size(size);
}
// We build the session globals and run `f` on the spawned thread, because
// `SessionGlobals` does not impl `Send` in the non-parallel compiler.
thread::scope(|s| {
// `unwrap` is ok here because `spawn_scoped` only panics if the thread
// name contains null bytes.
let r = builder
@@ -151,55 +150,57 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
match r {
Ok(v) => v,
Err(e) => panic::resume_unwind(e),
Err(e) => std::panic::resume_unwind(e),
}
})
}
/// Creates a new thread and forwards information in thread locals to it.
/// The new thread runs the deadlock handler.
/// Must only be called when a deadlock is about to happen.
#[cfg(parallel_compiler)]
unsafe fn handle_deadlock() {
let registry = rustc_rayon_core::Registry::current();
let query_map = tls::with(|tcx| {
QueryCtxt::from_tcx(tcx)
.try_collect_active_jobs()
.expect("active jobs shouldn't be locked in deadlock handler")
});
thread::spawn(move || rustc_query_impl::deadlock(query_map, &registry));
}
#[cfg(parallel_compiler)]
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
edition: Edition,
threads: usize,
f: F,
) -> R {
let mut config = rayon::ThreadPoolBuilder::new()
use rustc_data_structures::jobserver;
use rustc_middle::ty::tls;
use rustc_query_impl::{deadlock, QueryContext, QueryCtxt};
let mut builder = rayon::ThreadPoolBuilder::new()
.thread_name(|_| "rustc".to_string())
.acquire_thread_handler(jobserver::acquire_thread)
.release_thread_handler(jobserver::release_thread)
.num_threads(threads)
.deadlock_handler(|| unsafe { handle_deadlock() });
.deadlock_handler(|| {
// On deadlock, creates a new thread and forwards information in thread
// locals to it. The new thread runs the deadlock handler.
let query_map = tls::with(|tcx| {
QueryCtxt::from_tcx(tcx)
.try_collect_active_jobs()
.expect("active jobs shouldn't be locked in deadlock handler")
});
let registry = rustc_rayon_core::Registry::current();
thread::spawn(move || deadlock(query_map, &registry));
});
if let Some(size) = get_stack_size() {
config = config.stack_size(size);
builder = builder.stack_size(size);
}
let with_pool = move |pool: &rayon::ThreadPool| pool.install(f);
// We create the session globals on the main thread, then create the thread
// pool. Upon creation, each worker thread created gets a copy of the
// session globals in TLS. This is possible because `SessionGlobals` impls
// `Send` in the parallel compiler.
rustc_span::create_session_globals_then(edition, || {
rustc_span::with_session_globals(|session_globals| {
// The main handler runs for each Rayon worker thread and sets up
// the thread local rustc uses. `session_globals` is captured and set
// on the new threads.
let main_handler = move |thread: rayon::ThreadBuilder| {
rustc_span::set_session_globals_then(session_globals, || thread.run())
};
config.build_scoped(main_handler, with_pool).unwrap()
builder
.build_scoped(
// Initialize each new worker thread when created.
move |thread: rayon::ThreadBuilder| {
rustc_span::set_session_globals_then(session_globals, || thread.run())
},
// Run `f` on the first thread in the thread pool.
move |pool: &rayon::ThreadPool| pool.install(f),
)
.unwrap()
})
})
}
+3 -3
View File
@@ -1939,11 +1939,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
match ty.kind {
TyKind::ImplicitSelf => true,
TyKind::Path(None, _) => {
let path_res = self.r.partial_res_map[&ty.id].expect_full_res();
if let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path_res {
let path_res = self.r.partial_res_map[&ty.id].full_res();
if let Some(Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }) = path_res {
return true;
}
Some(path_res) == self.impl_self
self.impl_self.is_some() && path_res == self.impl_self
}
_ => false,
}
+4 -4
View File
@@ -994,14 +994,14 @@ extern "rust-intrinsic" {
/// `transmute` is semantically equivalent to a bitwise move of one type
/// into another. It copies the bits from the source value into the
/// destination value, then forgets the original. Note that source and destination
/// are passed by-value, which means if `T` or `U` contain padding, that padding
/// are passed by-value, which means if `Src` or `Dst` contain padding, that padding
/// is *not* guaranteed to be preserved by `transmute`.
///
/// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at
/// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler
/// will generate code *assuming that you, the programmer, ensure that there will never be
/// undefined behavior*. It is therefore your responsibility to guarantee that every value
/// passed to `transmute` is valid at both types `T` and `U`. Failing to uphold this condition
/// passed to `transmute` is valid at both types `Src` and `Dst`. Failing to uphold this condition
/// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly
/// unsafe**. `transmute` should be the absolute last resort.
///
@@ -1012,7 +1012,7 @@ extern "rust-intrinsic" {
///
/// Because `transmute` is a by-value operation, alignment of the *transmuted values
/// themselves* is not a concern. As with any other function, the compiler already ensures
/// both `T` and `U` are properly aligned. However, when transmuting values that *point
/// both `Src` and `Dst` are properly aligned. However, when transmuting values that *point
/// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
/// alignment of the pointed-to values.
///
@@ -1248,7 +1248,7 @@ extern "rust-intrinsic" {
#[rustc_allowed_through_unstable_modules]
#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
#[rustc_diagnostic_item = "transmute"]
pub fn transmute<T, U>(e: T) -> U;
pub fn transmute<Src, Dst>(src: Src) -> Dst;
/// Returns `true` if the actual type given as `T` requires drop
/// glue; returns `false` if the actual type provided for `T`
+19 -16
View File
@@ -1008,18 +1008,18 @@ pub fn copy<T: Copy>(x: &T) -> T {
*x
}
/// Interprets `src` as having type `&U`, and then reads `src` without moving
/// Interprets `src` as having type `&Dst`, and then reads `src` without moving
/// the contained value.
///
/// This function will unsafely assume the pointer `src` is valid for [`size_of::<U>`][size_of]
/// bytes by transmuting `&T` to `&U` and then reading the `&U` (except that this is done in a way
/// that is correct even when `&U` has stricter alignment requirements than `&T`). It will also
/// unsafely create a copy of the contained value instead of moving out of `src`.
/// This function will unsafely assume the pointer `src` is valid for [`size_of::<Dst>`][size_of]
/// bytes by transmuting `&Src` to `&Dst` and then reading the `&Dst` (except that this is done
/// in a way that is correct even when `&Dst` has stricter alignment requirements than `&Src`).
/// It will also unsafely create a copy of the contained value instead of moving out of `src`.
///
/// It is not a compile-time error if `T` and `U` have different sizes, but it
/// is highly encouraged to only invoke this function where `T` and `U` have the
/// same size. This function triggers [undefined behavior][ub] if `U` is larger than
/// `T`.
/// It is not a compile-time error if `Src` and `Dst` have different sizes, but it
/// is highly encouraged to only invoke this function where `Src` and `Dst` have the
/// same size. This function triggers [undefined behavior][ub] if `Dst` is larger than
/// `Src`.
///
/// [ub]: ../../reference/behavior-considered-undefined.html
///
@@ -1052,19 +1052,22 @@ pub fn copy<T: Copy>(x: &T) -> T {
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_transmute_copy", issue = "83165")]
pub const unsafe fn transmute_copy<T, U>(src: &T) -> U {
assert!(size_of::<T>() >= size_of::<U>(), "cannot transmute_copy if U is larger than T");
pub const unsafe fn transmute_copy<Src, Dst>(src: &Src) -> Dst {
assert!(
size_of::<Src>() >= size_of::<Dst>(),
"cannot transmute_copy if Dst is larger than Src"
);
// If U has a higher alignment requirement, src might not be suitably aligned.
if align_of::<U>() > align_of::<T>() {
// If Dst has a higher alignment requirement, src might not be suitably aligned.
if align_of::<Dst>() > align_of::<Src>() {
// SAFETY: `src` is a reference which is guaranteed to be valid for reads.
// The caller must guarantee that the actual transmutation is safe.
unsafe { ptr::read_unaligned(src as *const T as *const U) }
unsafe { ptr::read_unaligned(src as *const Src as *const Dst) }
} else {
// SAFETY: `src` is a reference which is guaranteed to be valid for reads.
// We just checked that `src as *const U` was properly aligned.
// We just checked that `src as *const Dst` was properly aligned.
// The caller must guarantee that the actual transmutation is safe.
unsafe { ptr::read(src as *const T as *const U) }
unsafe { ptr::read(src as *const Src as *const Dst) }
}
}
+5 -1
View File
@@ -130,7 +130,11 @@ fn test_transmute_copy_grow_panics() {
payload
.downcast::<&'static str>()
.and_then(|s| {
if *s == "cannot transmute_copy if U is larger than T" { Ok(s) } else { Err(s) }
if *s == "cannot transmute_copy if Dst is larger than Src" {
Ok(s)
} else {
Err(s)
}
})
.unwrap_or_else(|p| panic::resume_unwind(p));
}
+1 -1
View File
@@ -356,7 +356,7 @@ impl Instant {
///
/// # Panics
///
/// Previous rust versions panicked when self was earlier than the current time. Currently this
/// Previous rust versions panicked when the current time was earlier than self. Currently this
/// method returns a Duration of zero in that case. Future versions may reintroduce the panic.
/// See [Monotonicity].
///
@@ -1,7 +1,7 @@
# armeb-unknown-linux-gnueabi
**Tier: 3**
Target for cross-compiling Linux user-mode applications targetting the ARM BE8 architecture.
Target for cross-compiling Linux user-mode applications targeting the ARM BE8 architecture.
## Overview
BE8 architecture retains the same little-endian ordered code-stream used by conventional little endian ARM systems, however the data accesses are in big-endian. BE8 is used primarily in high-performance networking applications where the ability to read packets in their native "Network Byte Order" is important (many network protocols transmit data in big-endian byte order for their wire formats).
+30 -29
View File
@@ -409,9 +409,12 @@ function loadCss(cssFileName) {
break;
case "+":
ev.preventDefault();
expandAllDocs();
break;
case "-":
ev.preventDefault();
toggleAllDocs();
collapseAllDocs();
break;
case "?":
@@ -614,15 +617,31 @@ function loadCss(cssFileName) {
sidebarElems.appendChild(ul);
}
function expandAllDocs() {
const innerToggle = document.getElementById(toggleAllDocsId);
removeClass(innerToggle, "will-expand");
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
if (!hasClass(e, "type-contents-toggle")) {
e.open = true;
}
});
innerToggle.title = "collapse all docs";
innerToggle.children[0].innerText = "\u2212"; // "\u2212" is "" minus sign
}
function labelForToggleButton(sectionIsCollapsed) {
if (sectionIsCollapsed) {
// button will expand the section
return "+";
}
// button will collapse the section
// note that this text is also set in the HTML template in ../render/mod.rs
return "\u2212"; // "\u2212" is "" minus sign
function collapseAllDocs() {
const innerToggle = document.getElementById(toggleAllDocsId);
addClass(innerToggle, "will-expand");
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
if (e.parentNode.id !== "implementations-list" ||
(!hasClass(e, "implementors-toggle") &&
!hasClass(e, "type-contents-toggle"))
) {
e.open = false;
}
});
innerToggle.title = "expand all docs";
innerToggle.children[0].innerText = "+";
}
function toggleAllDocs() {
@@ -630,29 +649,11 @@ function loadCss(cssFileName) {
if (!innerToggle) {
return;
}
let sectionIsCollapsed = false;
if (hasClass(innerToggle, "will-expand")) {
removeClass(innerToggle, "will-expand");
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
if (!hasClass(e, "type-contents-toggle")) {
e.open = true;
}
});
innerToggle.title = "collapse all docs";
expandAllDocs();
} else {
addClass(innerToggle, "will-expand");
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
if (e.parentNode.id !== "implementations-list" ||
(!hasClass(e, "implementors-toggle") &&
!hasClass(e, "type-contents-toggle"))
) {
e.open = false;
}
});
sectionIsCollapsed = true;
innerToggle.title = "expand all docs";
collapseAllDocs();
}
innerToggle.children[0].innerText = labelForToggleButton(sectionIsCollapsed);
}
(function() {
+18
View File
@@ -11,3 +11,21 @@ press-key: "?"
assert-css: ("#help-button .popover", {"display": "block"})
press-key: "Escape"
assert-css: ("#help-button .popover", {"display": "none"})
// Checking doc collapse and expand.
// It should be displaying a "-":
assert-text: ("#toggle-all-docs", "[\u2212]")
press-key: "-"
wait-for-text: ("#toggle-all-docs", "[+]")
assert-attribute: ("#toggle-all-docs", {"class": "will-expand"})
// Pressing it again shouldn't do anything.
press-key: "-"
assert-text: ("#toggle-all-docs", "[+]")
assert-attribute: ("#toggle-all-docs", {"class": "will-expand"})
// Expanding now.
press-key: "+"
wait-for-text: ("#toggle-all-docs", "[\u2212]")
assert-attribute: ("#toggle-all-docs", {"class": ""})
// Pressing it again shouldn't do anything.
press-key: "+"
assert-text: ("#toggle-all-docs", "[\u2212]")
assert-attribute: ("#toggle-all-docs", {"class": ""})
+3 -3
View File
@@ -2,12 +2,12 @@ error[E0282]: type annotations needed
--> $DIR/issue-6458-3.rs:4:5
|
LL | mem::transmute(0);
| ^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `transmute`
| ^^^^^^^^^^^^^^ cannot infer type of the type parameter `Dst` declared on the function `transmute`
|
help: consider specifying the generic arguments
|
LL | mem::transmute::<i32, U>(0);
| ++++++++++
LL | mem::transmute::<i32, Dst>(0);
| ++++++++++++
error: aborting due to previous error
+7
View File
@@ -0,0 +1,7 @@
struct S {}
impl S {
fn f(self: &S::x) {} //~ ERROR ambiguous associated type
}
fn main() {}
+9
View File
@@ -0,0 +1,9 @@
error[E0223]: ambiguous associated type
--> $DIR/issue-103202.rs:4:17
|
LL | fn f(self: &S::x) {}
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::x`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0223`.
@@ -0,0 +1,9 @@
#![feature(const_trait_impl)]
#[const_trait]
trait Bar {}
fn foo<T>() where T: ~const Bar {}
//~^ ERROR `~const` is not allowed
fn main() {}
@@ -0,0 +1,14 @@
error: `~const` is not allowed here
--> $DIR/issue-90052.rs:6:22
|
LL | fn foo<T>() where T: ~const Bar {}
| ^^^^^^^^^^
|
note: this function is not `const`, so it cannot have `~const` trait bounds
--> $DIR/issue-90052.rs:6:4
|
LL | fn foo<T>() where T: ~const Bar {}
| ^^^
error: aborting due to previous error
@@ -1,4 +1,3 @@
// check-pass
#![feature(const_trait_impl)]
#![feature(generic_arg_infer)]
#![feature(generic_const_exprs)]
@@ -24,6 +23,7 @@ impl const Add42 for () {
}
fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
//~^ ERROR `~const` is not allowed here
Foo
}
@@ -0,0 +1,14 @@
error: `~const` is not allowed here
--> $DIR/tilde-const-and-const-params.rs:25:11
|
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
| ^^^^^^^^^^^^
|
note: this function is not `const`, so it cannot have `~const` trait bounds
--> $DIR/tilde-const-and-const-params.rs:25:4
|
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
| ^^^
error: aborting due to previous error
@@ -4,7 +4,7 @@ error: `~const` is not allowed here
LL | fn rpit() -> impl ~const T { S }
| ^^^^^^^^
|
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
= note: `impl Trait`s cannot have `~const` trait bounds
error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:12:17
@@ -12,7 +12,7 @@ error: `~const` is not allowed here
LL | fn apit(_: impl ~const T) {}
| ^^^^^^^^
|
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
= note: `impl Trait`s cannot have `~const` trait bounds
error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:15:50
@@ -20,7 +20,7 @@ error: `~const` is not allowed here
LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
| ^^^^^^^^
|
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
= note: `impl Trait`s cannot have `~const` trait bounds
error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:18:48
@@ -28,7 +28,7 @@ error: `~const` is not allowed here
LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
| ^^^^^^^^
|
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
= note: `impl Trait`s cannot have `~const` trait bounds
error: `~const` and `?` are mutually exclusive
--> $DIR/tilde-const-invalid-places.rs:21:25
-1
View File
@@ -217,7 +217,6 @@ trigger_files = [
[autolabel."A-testsuite"]
trigger_files = [
"src/test",
"src/ci",
"src/tools/compiletest",
"src/tools/cargotest",