Auto merge of #119777 - GuillaumeGomez:rollup-mf82vow, r=GuillaumeGomez
Rollup of 5 pull requests Successful merges: - #118241 (Making `User<T>` and `User<[T]>` `Send`) - #118645 (chore: Bump compiler_builtins) - #118680 (Add support for shell argfiles) - #119721 (`~const` trait and projection bounds do not imply their non-const counterparts) - #119768 (core: panic: fix broken link) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ae9d24de80
35 changed files with 414 additions and 151 deletions
|
@ -704,9 +704,9 @@ checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335"
|
|||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.103"
|
||||
version = "0.1.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3b73c3443a5fd2438d7ba4853c64e4c8efc2404a9e28a9234cc2d5eebc6c242"
|
||||
checksum = "99c3f9035afc33f4358773239573f7d121099856753e1bbd2a6a5207098fc741"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"rustc-std-workspace-core",
|
||||
|
@ -3738,6 +3738,7 @@ dependencies = [
|
|||
"rustc_trait_selection",
|
||||
"rustc_ty_utils",
|
||||
"serde_json",
|
||||
"shlex",
|
||||
"time",
|
||||
"tracing",
|
||||
"windows",
|
||||
|
|
|
@ -50,6 +50,7 @@ rustc_target = { path = "../rustc_target" }
|
|||
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
||||
rustc_ty_utils = { path = "../rustc_ty_utils" }
|
||||
serde_json = "1.0.59"
|
||||
shlex = "1.0"
|
||||
time = { version = "0.3", default-features = false, features = ["alloc", "formatting"] }
|
||||
tracing = { version = "0.1.35" }
|
||||
# tidy-alphabetical-end
|
||||
|
|
|
@ -5,18 +5,92 @@ use std::io;
|
|||
|
||||
use rustc_session::EarlyDiagCtxt;
|
||||
|
||||
fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
|
||||
if let Some(path) = arg.strip_prefix('@') {
|
||||
let file = match fs::read_to_string(path) {
|
||||
Ok(file) => file,
|
||||
Err(ref err) if err.kind() == io::ErrorKind::InvalidData => {
|
||||
return Err(Error::Utf8Error(Some(path.to_string())));
|
||||
/// Expands argfiles in command line arguments.
|
||||
#[derive(Default)]
|
||||
struct Expander {
|
||||
shell_argfiles: bool,
|
||||
next_is_unstable_option: bool,
|
||||
expanded: Vec<String>,
|
||||
}
|
||||
|
||||
impl Expander {
|
||||
/// Handles the next argument. If the argument is an argfile, it is expanded
|
||||
/// inline.
|
||||
fn arg(&mut self, arg: &str) -> Result<(), Error> {
|
||||
if let Some(argfile) = arg.strip_prefix('@') {
|
||||
match argfile.split_once(':') {
|
||||
Some(("shell", path)) if self.shell_argfiles => {
|
||||
shlex::split(&Self::read_file(path)?)
|
||||
.ok_or_else(|| Error::ShellParseError(path.to_string()))?
|
||||
.into_iter()
|
||||
.for_each(|arg| self.push(arg));
|
||||
}
|
||||
_ => {
|
||||
let contents = Self::read_file(argfile)?;
|
||||
contents.lines().for_each(|arg| self.push(arg.to_string()));
|
||||
}
|
||||
}
|
||||
Err(err) => return Err(Error::IOError(path.to_string(), err)),
|
||||
};
|
||||
Ok(file.lines().map(ToString::to_string).collect())
|
||||
} else {
|
||||
Ok(vec![arg])
|
||||
} else {
|
||||
self.push(arg.to_string());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Adds a command line argument verbatim with no argfile expansion.
|
||||
fn push(&mut self, arg: String) {
|
||||
// Unfortunately, we have to do some eager argparsing to handle unstable
|
||||
// options which change the behavior of argfile arguments.
|
||||
//
|
||||
// Normally, all of the argfile arguments (e.g. `@args.txt`) are
|
||||
// expanded into our arguments list *and then* the whole list of
|
||||
// arguments are passed on to be parsed. However, argfile parsing
|
||||
// options like `-Zshell_argfiles` need to change the behavior of that
|
||||
// argument expansion. So we have to do a little parsing on our own here
|
||||
// instead of leaning on the existing logic.
|
||||
//
|
||||
// All we care about are unstable options, so we parse those out and
|
||||
// look for any that affect how we expand argfiles. This argument
|
||||
// inspection is very conservative; we only change behavior when we see
|
||||
// exactly the options we're looking for and everything gets passed
|
||||
// through.
|
||||
|
||||
if self.next_is_unstable_option {
|
||||
self.inspect_unstable_option(&arg);
|
||||
self.next_is_unstable_option = false;
|
||||
} else if let Some(unstable_option) = arg.strip_prefix("-Z") {
|
||||
if unstable_option.is_empty() {
|
||||
self.next_is_unstable_option = true;
|
||||
} else {
|
||||
self.inspect_unstable_option(unstable_option);
|
||||
}
|
||||
}
|
||||
|
||||
self.expanded.push(arg);
|
||||
}
|
||||
|
||||
/// Consumes the `Expander`, returning the expanded arguments.
|
||||
fn finish(self) -> Vec<String> {
|
||||
self.expanded
|
||||
}
|
||||
|
||||
/// Parses any relevant unstable flags specified on the command line.
|
||||
fn inspect_unstable_option(&mut self, option: &str) {
|
||||
match option {
|
||||
"shell-argfiles" => self.shell_argfiles = true,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads the contents of a file as UTF-8.
|
||||
fn read_file(path: &str) -> Result<String, Error> {
|
||||
fs::read_to_string(path).map_err(|e| {
|
||||
if e.kind() == io::ErrorKind::InvalidData {
|
||||
Error::Utf8Error(Some(path.to_string()))
|
||||
} else {
|
||||
Error::IOError(path.to_string(), e)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,20 +98,20 @@ fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
|
|||
/// If this function is intended to be used with command line arguments,
|
||||
/// `argv[0]` must be removed prior to calling it manually.
|
||||
pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec<String> {
|
||||
let mut args = Vec::new();
|
||||
let mut expander = Expander::default();
|
||||
for arg in at_args {
|
||||
match arg_expand(arg.clone()) {
|
||||
Ok(arg) => args.extend(arg),
|
||||
Err(err) => early_dcx.early_fatal(format!("Failed to load argument file: {err}")),
|
||||
if let Err(err) = expander.arg(arg) {
|
||||
early_dcx.early_fatal(format!("Failed to load argument file: {err}"));
|
||||
}
|
||||
}
|
||||
args
|
||||
expander.finish()
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
Utf8Error(Option<String>),
|
||||
IOError(String, io::Error),
|
||||
ShellParseError(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
|
@ -46,6 +120,7 @@ impl fmt::Display for Error {
|
|||
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::ShellParseError(path) => write!(fmt, "Invalid shell-style arguments in {path}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1032,7 +1032,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
self.trait_defines_associated_item_named(r.def_id(), assoc_kind, assoc_name)
|
||||
});
|
||||
|
||||
let Some(mut bound) = matching_candidates.next() else {
|
||||
let Some(bound) = matching_candidates.next() else {
|
||||
let reported = self.complain_about_assoc_item_not_found(
|
||||
all_candidates,
|
||||
&ty_param_name.to_string(),
|
||||
|
@ -1046,38 +1046,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
};
|
||||
debug!(?bound);
|
||||
|
||||
// look for a candidate that is not the same as our first bound, disregarding
|
||||
// whether the bound is const.
|
||||
let mut next_cand = matching_candidates.next();
|
||||
while let Some(mut bound2) = next_cand {
|
||||
debug!(?bound2);
|
||||
if bound2.bound_vars() != bound.bound_vars() {
|
||||
break;
|
||||
}
|
||||
|
||||
let generics = tcx.generics_of(bound.def_id());
|
||||
let Some(host_index) = generics.host_effect_index else { break };
|
||||
|
||||
// always return the bound that contains the host param.
|
||||
if let ty::ConstKind::Param(_) = bound2.skip_binder().args.const_at(host_index).kind() {
|
||||
(bound, bound2) = (bound2, bound);
|
||||
}
|
||||
|
||||
let unconsted_args = bound
|
||||
.skip_binder()
|
||||
.args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(n, arg)| if host_index == n { tcx.consts.true_.into() } else { arg });
|
||||
|
||||
if unconsted_args.eq(bound2.skip_binder().args.iter()) {
|
||||
next_cand = matching_candidates.next();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(bound2) = next_cand {
|
||||
if let Some(bound2) = matching_candidates.next() {
|
||||
debug!(?bound2);
|
||||
|
||||
let assoc_kind_str = assoc_kind_str(assoc_kind);
|
||||
|
|
|
@ -45,24 +45,6 @@ impl<'tcx> Bounds<'tcx> {
|
|||
polarity: ty::ImplPolarity,
|
||||
) {
|
||||
self.push_trait_bound_inner(tcx, trait_ref, span, polarity);
|
||||
|
||||
// push a non-const (`host = true`) version of the bound if it is `~const`.
|
||||
if tcx.features().effects
|
||||
&& let Some(host_effect_idx) = tcx.generics_of(trait_ref.def_id()).host_effect_index
|
||||
&& trait_ref.skip_binder().args.const_at(host_effect_idx) != tcx.consts.true_
|
||||
{
|
||||
let generics = tcx.generics_of(trait_ref.def_id());
|
||||
let Some(host_index) = generics.host_effect_index else { return };
|
||||
let trait_ref = trait_ref.map_bound(|mut trait_ref| {
|
||||
trait_ref.args =
|
||||
tcx.mk_args_from_iter(trait_ref.args.iter().enumerate().map(|(n, arg)| {
|
||||
if host_index == n { tcx.consts.true_.into() } else { arg }
|
||||
}));
|
||||
trait_ref
|
||||
});
|
||||
|
||||
self.push_trait_bound_inner(tcx, trait_ref, span, polarity);
|
||||
}
|
||||
}
|
||||
|
||||
fn push_trait_bound_inner(
|
||||
|
|
|
@ -11,7 +11,7 @@ use rustc_hir::intravisit::{self, Visitor};
|
|||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, ToPredicate};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{sym, Span, DUMMY_SP};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
/// Returns a list of all type predicates (explicit and implicit) for the definition with
|
||||
/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
|
||||
|
@ -38,38 +38,12 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
|
|||
// an obligation and instead be skipped. Otherwise we'd use
|
||||
// `tcx.def_span(def_id);`
|
||||
let span = rustc_span::DUMMY_SP;
|
||||
let non_const_bound = if tcx.features().effects && tcx.has_attr(def_id, sym::const_trait) {
|
||||
// when `Self` is a const trait, also add `Self: Trait<.., true>` as implied bound,
|
||||
// because only implementing `Self: Trait<.., false>` is currently not possible.
|
||||
Some((
|
||||
ty::TraitRef::new(
|
||||
tcx,
|
||||
def_id,
|
||||
ty::GenericArgs::for_item(tcx, def_id, |param, _| {
|
||||
if param.is_host_effect() {
|
||||
tcx.consts.true_.into()
|
||||
} else {
|
||||
tcx.mk_param_from_def(param)
|
||||
}
|
||||
}),
|
||||
)
|
||||
.to_predicate(tcx),
|
||||
|
||||
result.predicates =
|
||||
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
|
||||
ty::TraitRef::identity(tcx, def_id).to_predicate(tcx),
|
||||
span,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
result.predicates = tcx.arena.alloc_from_iter(
|
||||
result
|
||||
.predicates
|
||||
.iter()
|
||||
.copied()
|
||||
.chain(std::iter::once((
|
||||
ty::TraitRef::identity(tcx, def_id).to_predicate(tcx),
|
||||
span,
|
||||
)))
|
||||
.chain(non_const_bound),
|
||||
);
|
||||
))));
|
||||
}
|
||||
debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
|
||||
result
|
||||
|
|
|
@ -698,6 +698,7 @@ fn test_unstable_options_tracking_hash() {
|
|||
untracked!(query_dep_graph, true);
|
||||
untracked!(self_profile, SwitchWithOptPath::Enabled(None));
|
||||
untracked!(self_profile_events, Some(vec![String::new()]));
|
||||
untracked!(shell_argfiles, true);
|
||||
untracked!(span_debug, true);
|
||||
untracked!(span_free_formats, true);
|
||||
untracked!(temps_dir, Some(String::from("abc")));
|
||||
|
|
|
@ -1841,6 +1841,8 @@ written to standard error output)"),
|
|||
query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes"),
|
||||
share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"make the current crate share its generic instantiations"),
|
||||
shell_argfiles: bool = (false, parse_bool, [UNTRACKED],
|
||||
"allow argument files to be specified with POSIX \"shell-style\" argument quoting"),
|
||||
show_span: Option<String> = (None, parse_opt_string, [TRACKED],
|
||||
"show spans for compiler debugging (expr|pat|ty)"),
|
||||
simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
|
||||
|
|
|
@ -56,7 +56,7 @@ For more detailed information about error handling check out the [book] or the
|
|||
[`panic_any`]: ../std/panic/fn.panic_any.html
|
||||
[`Box`]: ../std/boxed/struct.Box.html
|
||||
[`Any`]: crate::any::Any
|
||||
[`format!` syntax]: ../std/fmt/index.html
|
||||
[formatting syntax]: ../std/fmt/index.html
|
||||
[book]: ../book/ch09-00-error-handling.html
|
||||
[`std::result`]: ../std/result/index.html
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
|
|||
panic_abort = { path = "../panic_abort" }
|
||||
core = { path = "../core", public = true }
|
||||
libc = { version = "0.2.150", default-features = false, features = ['rustc-dep-of-std'], public = true }
|
||||
compiler_builtins = { version = "0.1.103" }
|
||||
compiler_builtins = { version = "0.1.104" }
|
||||
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
||||
unwind = { path = "../unwind" }
|
||||
hashbrown = { version = "0.14", default-features = false, features = ['rustc-dep-of-std'] }
|
||||
|
@ -54,8 +54,8 @@ hermit-abi = { version = "0.3.2", features = ['rustc-dep-of-std'], public = true
|
|||
wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
|
||||
|
||||
[target.'cfg(target_os = "uefi")'.dependencies]
|
||||
r-efi = { version = "4.2.0", features = ['rustc-dep-of-std']}
|
||||
r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std']}
|
||||
r-efi = { version = "4.2.0", features = ['rustc-dep-of-std'] }
|
||||
r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] }
|
||||
|
||||
[features]
|
||||
backtrace = [
|
||||
|
|
|
@ -185,6 +185,12 @@ pub struct UserRef<T: ?Sized>(UnsafeCell<T>);
|
|||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
pub struct User<T: UserSafe + ?Sized>(NonNull<UserRef<T>>);
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
unsafe impl<T: UserSafeSized> Send for User<T> {}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
unsafe impl<T: UserSafeSized> Send for User<[T]> {}
|
||||
|
||||
trait NewUserRef<T: ?Sized> {
|
||||
unsafe fn new_userref(v: T) -> Self;
|
||||
}
|
||||
|
|
11
src/doc/unstable-book/src/compiler-flags/shell-argfiles.md
Normal file
11
src/doc/unstable-book/src/compiler-flags/shell-argfiles.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# `shell-argfiles`
|
||||
|
||||
--------------------
|
||||
|
||||
The `-Zshell-argfiles` compiler flag allows argfiles to be parsed using POSIX
|
||||
"shell-style" quoting. When enabled, the compiler will use `shlex` to parse the
|
||||
arguments from argfiles specified with `@shell:<path>`.
|
||||
|
||||
Because this feature controls the parsing of input arguments, the
|
||||
`-Zshell-argfiles` flag must be present before the argument specifying the
|
||||
shell-style arguemnt file.
|
|
@ -325,6 +325,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||
"sha1",
|
||||
"sha2",
|
||||
"sharded-slab",
|
||||
"shlex",
|
||||
"smallvec",
|
||||
"snap",
|
||||
"stable_deref_trait",
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
|
|||
const ENTRY_LIMIT: usize = 900;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1849;
|
||||
const ROOT_ENTRY_LIMIT: usize = 867;
|
||||
const ROOT_ENTRY_LIMIT: usize = 868;
|
||||
|
||||
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
||||
"rs", // test source files
|
||||
|
@ -35,6 +35,10 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
|
|||
"tests/ui/macros/syntax-extension-source-utils-files/includeme.fragment", // more include
|
||||
"tests/ui/proc-macro/auxiliary/included-file.txt", // more include
|
||||
"tests/ui/invalid/foo.natvis.xml", // sample debugger visualizer
|
||||
"tests/ui/shell-argfiles/shell-argfiles.args", // passing args via a file
|
||||
"tests/ui/shell-argfiles/shell-argfiles-badquotes.args", // passing args via a file
|
||||
"tests/ui/shell-argfiles/shell-argfiles-via-argfile-shell.args", // passing args via a file
|
||||
"tests/ui/shell-argfiles/shell-argfiles-via-argfile.args", // passing args via a file
|
||||
];
|
||||
|
||||
fn check_entries(tests_path: &Path, bad: &mut bool) {
|
||||
|
|
|
@ -9,7 +9,7 @@ trait Foo {
|
|||
}
|
||||
|
||||
const fn foo<T: ~const Foo>() {
|
||||
<T as Foo>::Assoc::foo();
|
||||
<T as /* FIXME: ~const */ Foo>::Assoc::foo();
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -6,15 +6,17 @@ LL | type Assoc: ~const Foo;
|
|||
|
|
||||
= note: this item cannot have `~const` trait bounds
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/assoc-type-const-bound-usage.rs:12:5
|
||||
error[E0277]: the trait bound `T: Foo` is not satisfied
|
||||
--> $DIR/assoc-type-const-bound-usage.rs:12:6
|
||||
|
|
||||
LL | <T as Foo>::Assoc::foo();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `host`, found `true`
|
||||
LL | <T as /* FIXME: ~const */ Foo>::Assoc::foo();
|
||||
| ^ the trait `Foo` is not implemented for `T`
|
||||
|
|
||||
= note: expected constant `host`
|
||||
found constant `true`
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn foo<T: ~const Foo + Foo>() {
|
||||
| +++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
// check-pass
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![allow(internal_features)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![feature(
|
||||
auto_traits,
|
||||
const_trait_impl,
|
||||
effects,
|
||||
lang_items,
|
||||
no_core,
|
||||
staged_api,
|
||||
unboxed_closures
|
||||
)]
|
||||
#![stable(feature = "minicore", since = "1.0.0")]
|
||||
|
||||
fn test() {
|
||||
fn is_const_fn<F>(_: F)
|
||||
where
|
||||
F: const FnOnce<()>,
|
||||
{
|
||||
}
|
||||
|
||||
const fn foo() {}
|
||||
|
||||
is_const_fn(foo);
|
||||
}
|
||||
|
||||
/// ---------------------------------------------------------------------- ///
|
||||
/// Const fn trait definitions
|
||||
|
||||
#[const_trait]
|
||||
#[lang = "fn"]
|
||||
#[rustc_paren_sugar]
|
||||
trait Fn<Args: Tuple>: ~const FnMut<Args> {
|
||||
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
|
||||
}
|
||||
|
||||
#[const_trait]
|
||||
#[lang = "fn_mut"]
|
||||
#[rustc_paren_sugar]
|
||||
trait FnMut<Args: Tuple>: ~const FnOnce<Args> {
|
||||
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
|
||||
}
|
||||
|
||||
#[const_trait]
|
||||
#[lang = "fn_once"]
|
||||
#[rustc_paren_sugar]
|
||||
trait FnOnce<Args: Tuple> {
|
||||
#[lang = "fn_once_output"]
|
||||
type Output;
|
||||
|
||||
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
|
||||
}
|
||||
|
||||
/// ---------------------------------------------------------------------- ///
|
||||
/// All this other stuff needed for core. Unrelated to test.
|
||||
|
||||
#[lang = "destruct"]
|
||||
#[const_trait]
|
||||
trait Destruct {}
|
||||
|
||||
#[lang = "freeze"]
|
||||
unsafe auto trait Freeze {}
|
||||
|
||||
#[lang = "drop"]
|
||||
#[const_trait]
|
||||
trait Drop {
|
||||
fn drop(&mut self);
|
||||
}
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
#[lang = "tuple_trait"]
|
||||
trait Tuple {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {}
|
||||
|
||||
impl<T: ?Sized> Receiver for &T {}
|
||||
|
||||
impl<T: ?Sized> Receiver for &mut T {}
|
|
@ -1,4 +1,6 @@
|
|||
// known-bug: #110395
|
||||
// Broken until we have `&T: const Deref` impl in stdlib
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(
|
||||
associated_type_bounds,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0277]: can't compare `()` with `()`
|
||||
--> $DIR/const-impl-trait.rs:35:17
|
||||
--> $DIR/const-impl-trait.rs:37:17
|
||||
|
|
||||
LL | assert!(cmp(&()));
|
||||
| --- ^^^ no implementation for `() == ()`
|
||||
|
@ -9,23 +9,20 @@ LL | assert!(cmp(&()));
|
|||
= help: the trait `const PartialEq` is not implemented for `()`
|
||||
= help: the trait `PartialEq` is implemented for `()`
|
||||
note: required by a bound in `cmp`
|
||||
--> $DIR/const-impl-trait.rs:12:23
|
||||
--> $DIR/const-impl-trait.rs:14:23
|
||||
|
|
||||
LL | const fn cmp(a: &impl ~const PartialEq) -> bool {
|
||||
| ^^^^^^^^^^^^^^^^ required by this bound in `cmp`
|
||||
|
||||
error[E0277]: can't compare `&impl ~const PartialEq` with `&impl ~const PartialEq`
|
||||
--> $DIR/const-impl-trait.rs:13:7
|
||||
error[E0369]: binary operation `==` cannot be applied to type `&impl ~const PartialEq`
|
||||
--> $DIR/const-impl-trait.rs:15:7
|
||||
|
|
||||
LL | a == a
|
||||
| ^^ no implementation for `&impl ~const PartialEq == &impl ~const PartialEq`
|
||||
|
|
||||
= help: the trait `~const PartialEq<&impl ~const PartialEq>` is not implemented for `&impl ~const PartialEq`
|
||||
help: consider dereferencing both sides of the expression
|
||||
|
|
||||
LL | *a == *a
|
||||
| + +
|
||||
| - ^^ - &impl ~const PartialEq
|
||||
| |
|
||||
| &impl ~const PartialEq
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
Some errors have detailed explanations: E0277, E0369.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
|
|
@ -40,7 +40,7 @@ const fn bar() {
|
|||
|
||||
#[lang = "Try"]
|
||||
#[const_trait]
|
||||
trait Try: FromResidual {
|
||||
trait Try: FromResidual<Self::Residual> {
|
||||
type Output;
|
||||
type Residual;
|
||||
|
||||
|
@ -53,7 +53,7 @@ trait Try: FromResidual {
|
|||
|
||||
// FIXME
|
||||
// #[const_trait]
|
||||
trait FromResidual<R = <Self as Try>::Residual> {
|
||||
trait FromResidual<R = <Self as /* FIXME: ~const */ Try>::Residual> {
|
||||
#[lang = "from_residual"]
|
||||
fn from_residual(residual: R) -> Self;
|
||||
}
|
||||
|
@ -519,9 +519,14 @@ extern "rust-intrinsic" {
|
|||
called_in_const: F,
|
||||
called_at_rt: G,
|
||||
) -> RET
|
||||
/* where clauses enforced by built-in method confirmation:
|
||||
where
|
||||
F: const FnOnce<Arg, Output = RET>,
|
||||
G: FnOnce<Arg, Output = RET>,
|
||||
*/;
|
||||
F: const FnOnce<ARG, Output = RET>,
|
||||
G: FnOnce<ARG, Output = RET>;
|
||||
}
|
||||
|
||||
fn test_const_eval_select() {
|
||||
const fn const_fn() {}
|
||||
fn rt_fn() {}
|
||||
|
||||
unsafe { const_eval_select((), const_fn, rt_fn); }
|
||||
}
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
// check-pass
|
||||
// known-bug: #110395
|
||||
// FIXME: effects
|
||||
|
||||
#![feature(const_trait_impl, effects)]
|
||||
|
||||
pub trait Owo<X = <Self as Uwu>::T> {}
|
||||
// This fails because `~const Uwu` doesn't imply (non-const) `Uwu`.
|
||||
|
||||
// FIXME: #[const_trait]
|
||||
pub trait Owo<X = <Self as /* FIXME: ~const */ Uwu>::T> {}
|
||||
|
||||
#[const_trait]
|
||||
pub trait Uwu: Owo {
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
error[E0277]: the trait bound `Self: Uwu` is not satisfied
|
||||
--> $DIR/project.rs:12:1
|
||||
|
|
||||
LL | pub trait Uwu: Owo {
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `Uwu` is not implemented for `Self`
|
||||
|
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | pub trait Uwu: Owo + Uwu {
|
||||
| +++++
|
||||
|
||||
error[E0277]: the trait bound `Self: Uwu` is not satisfied
|
||||
--> $DIR/project.rs:12:1
|
||||
|
|
||||
LL | / pub trait Uwu: Owo {
|
||||
LL | | type T;
|
||||
LL | | }
|
||||
| |_^ the trait `Uwu` is not implemented for `Self`
|
||||
|
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | pub trait Uwu: Owo + Uwu {
|
||||
| +++++
|
||||
|
||||
error[E0277]: the trait bound `Self: Uwu` is not satisfied
|
||||
--> $DIR/project.rs:12:16
|
||||
|
|
||||
LL | pub trait Uwu: Owo {
|
||||
| ^^^ the trait `Uwu` is not implemented for `Self`
|
||||
|
|
||||
note: required by a bound in `Owo`
|
||||
--> $DIR/project.rs:9:15
|
||||
|
|
||||
LL | pub trait Owo<X = <Self as /* FIXME: ~const */ Uwu>::T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Owo`
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | pub trait Uwu: Owo + Uwu {
|
||||
| +++++
|
||||
|
||||
error[E0277]: the trait bound `Self: Uwu` is not satisfied
|
||||
--> $DIR/project.rs:13:5
|
||||
|
|
||||
LL | type T;
|
||||
| ^^^^^^ the trait `Uwu` is not implemented for `Self`
|
||||
|
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | pub trait Uwu: Owo + Uwu {
|
||||
| +++++
|
||||
|
||||
error[E0277]: the trait bound `Self: Uwu` is not satisfied
|
||||
--> $DIR/project.rs:13:5
|
||||
|
|
||||
LL | type T;
|
||||
| ^^^^^^^ the trait `Uwu` is not implemented for `Self`
|
||||
|
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | pub trait Uwu: Owo + Uwu {
|
||||
| +++++
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -1,21 +1,35 @@
|
|||
error[E0308]: mismatched types
|
||||
error[E0277]: the trait bound `T: ~const Bar` is not satisfied
|
||||
--> $DIR/trait-where-clause-const.rs:21:5
|
||||
|
|
||||
LL | T::b();
|
||||
| ^^^^^^ expected `host`, found `true`
|
||||
| ^ the trait `~const Bar` is not implemented for `T`
|
||||
|
|
||||
= note: expected constant `host`
|
||||
found constant `true`
|
||||
note: required by a bound in `Foo::b`
|
||||
--> $DIR/trait-where-clause-const.rs:15:24
|
||||
|
|
||||
LL | fn b() where Self: ~const Bar;
|
||||
| ^^^^^^^^^^ required by this bound in `Foo::b`
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
|
||||
| ++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/trait-where-clause-const.rs:23:5
|
||||
error[E0277]: the trait bound `T: ~const Bar` is not satisfied
|
||||
--> $DIR/trait-where-clause-const.rs:23:12
|
||||
|
|
||||
LL | T::c::<T>();
|
||||
| ^^^^^^^^^^^ expected `host`, found `true`
|
||||
| ^ the trait `~const Bar` is not implemented for `T`
|
||||
|
|
||||
= note: expected constant `host`
|
||||
found constant `true`
|
||||
note: required by a bound in `Foo::c`
|
||||
--> $DIR/trait-where-clause-const.rs:16:13
|
||||
|
|
||||
LL | fn c<T: ~const Bar>();
|
||||
| ^^^^^^^^^^ required by this bound in `Foo::c`
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
|
||||
| ++++++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
@ -30,4 +30,4 @@ fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
|
|||
// FIXME(effects): Instead of suggesting `+ const Trait`, suggest
|
||||
// changing `~const Trait` to `const Trait`.
|
||||
const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
|
||||
//~^ ERROR the trait bound `T: const Trait` is not satisfied
|
||||
//~^ ERROR mismatched types
|
||||
|
|
|
@ -7,16 +7,14 @@ LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
|
|||
= note: expected constant `false`
|
||||
found constant `true`
|
||||
|
||||
error[E0277]: the trait bound `T: const Trait` is not satisfied
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/unsatisfied-const-trait-bound.rs:32:50
|
||||
|
|
||||
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
|
||||
| ^ the trait `const Trait` is not implemented for `T`
|
||||
| ^^^^^^^^^ expected `false`, found `host`
|
||||
|
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn accept1<T: ~const Trait + const Trait>(_: Container<{ T::make() }>) {}
|
||||
| +++++++++++++
|
||||
= note: expected constant `false`
|
||||
found constant `host`
|
||||
|
||||
error[E0277]: the trait bound `Ty: const Trait` is not satisfied
|
||||
--> $DIR/unsatisfied-const-trait-bound.rs:20:15
|
||||
|
|
11
tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.rs
Normal file
11
tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Check to see if we can get parameters from an @argsfile file
|
||||
//
|
||||
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
|
||||
// separators. This test uses backslash as the path separator for the command
|
||||
// line arguments and is only run on windows.
|
||||
//
|
||||
// only-windows
|
||||
// compile-flags: --cfg cmdline_set -Z shell-argfiles @shell:{{src-base}}\shell-argfiles\shell-argfiles-badquotes.args
|
||||
|
||||
fn main() {
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
error: Failed to load argument file: Invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args
|
||||
|
1
tests/ui/shell-argfiles/shell-argfiles-badquotes.args
Normal file
1
tests/ui/shell-argfiles/shell-argfiles-badquotes.args
Normal file
|
@ -0,0 +1 @@
|
|||
"--cfg" "unquoted_set
|
12
tests/ui/shell-argfiles/shell-argfiles-badquotes.rs
Normal file
12
tests/ui/shell-argfiles/shell-argfiles-badquotes.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Check to see if we can get parameters from an @argsfile file
|
||||
//
|
||||
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
|
||||
// separators. We have a duplicated version of this test that uses backslash as
|
||||
// the path separator for the command line arguments that is only run on
|
||||
// windows.
|
||||
//
|
||||
// ignore-windows
|
||||
// compile-flags: --cfg cmdline_set -Z shell-argfiles @shell:{{src-base}}/shell-argfiles/shell-argfiles-badquotes.args
|
||||
|
||||
fn main() {
|
||||
}
|
2
tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr
Normal file
2
tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr
Normal file
|
@ -0,0 +1,2 @@
|
|||
error: Failed to load argument file: Invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args
|
||||
|
|
@ -0,0 +1 @@
|
|||
"--cfg" "shell_args_set"
|
1
tests/ui/shell-argfiles/shell-argfiles-via-argfile.args
Normal file
1
tests/ui/shell-argfiles/shell-argfiles-via-argfile.args
Normal file
|
@ -0,0 +1 @@
|
|||
-Zshell-argfiles
|
10
tests/ui/shell-argfiles/shell-argfiles-via-argfile.rs
Normal file
10
tests/ui/shell-argfiles/shell-argfiles-via-argfile.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Check to see if we can get parameters from an @argsfile file
|
||||
//
|
||||
// build-pass
|
||||
// compile-flags: @{{src-base}}/shell-argfiles/shell-argfiles-via-argfile.args @shell:{{src-base}}/shell-argfiles/shell-argfiles-via-argfile-shell.args
|
||||
|
||||
#[cfg(not(shell_args_set))]
|
||||
compile_error!("shell_args_set not set");
|
||||
|
||||
fn main() {
|
||||
}
|
3
tests/ui/shell-argfiles/shell-argfiles.args
Normal file
3
tests/ui/shell-argfiles/shell-argfiles.args
Normal file
|
@ -0,0 +1,3 @@
|
|||
--cfg unquoted_set
|
||||
'--cfg' 'single_quoted_set'
|
||||
"--cfg" "double_quoted_set"
|
19
tests/ui/shell-argfiles/shell-argfiles.rs
Normal file
19
tests/ui/shell-argfiles/shell-argfiles.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Check to see if we can get parameters from an @argsfile file
|
||||
//
|
||||
// build-pass
|
||||
// compile-flags: --cfg cmdline_set -Z shell-argfiles @shell:{{src-base}}/shell-argfiles/shell-argfiles.args
|
||||
|
||||
#[cfg(not(cmdline_set))]
|
||||
compile_error!("cmdline_set not set");
|
||||
|
||||
#[cfg(not(unquoted_set))]
|
||||
compile_error!("unquoted_set not set");
|
||||
|
||||
#[cfg(not(single_quoted_set))]
|
||||
compile_error!("single_quoted_set not set");
|
||||
|
||||
#[cfg(not(double_quoted_set))]
|
||||
compile_error!("double_quoted_set not set");
|
||||
|
||||
fn main() {
|
||||
}
|
Loading…
Add table
Reference in a new issue