Auto merge of #93921 - matthiaskrgr:rollup-wn3jlxj, r=matthiaskrgr

Rollup of 10 pull requests

Successful merges:

 - #90955 (Rename `FilenameTooLong` to `InvalidFilename` and also use it for Windows' `ERROR_INVALID_NAME`)
 - #91607 (Make `span_extend_to_prev_str()` more robust)
 - #92895 (Remove some unused functionality)
 - #93635 (Add missing platform-specific information on current_dir and set_current_dir)
 - #93660 (rustdoc-json: Add some tests for typealias item)
 - #93782 (Split `pauth` target feature)
 - #93868 (Fix incorrect register conflict detection in asm!)
 - #93888 (Implement `AsFd` for `&T` and `&mut T`.)
 - #93909 (Fix typo: explicitely -> explicitly)
 - #93910 (fix mention of moved function in `rustc_hir` docs)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-02-11 23:01:50 +00:00
commit f19851069e
41 changed files with 487 additions and 99 deletions

View file

@ -373,7 +373,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
err.emit();
}
Entry::Vacant(v) => {
v.insert(idx);
if r == reg {
v.insert(idx);
}
}
}
};

View file

@ -11,7 +11,6 @@ pub fn inject(
mut krate: ast::Crate,
resolver: &mut dyn ResolverExpand,
sess: &Session,
alt_std_name: Option<Symbol>,
) -> ast::Crate {
let edition = sess.parse_sess.edition;
@ -53,7 +52,7 @@ pub fn inject(
span,
ident,
vec![cx.attribute(cx.meta_word(span, sym::macro_use))],
ast::ItemKind::ExternCrate(alt_std_name),
ast::ItemKind::ExternCrate(None),
),
);
}

View file

@ -322,12 +322,33 @@ pub fn from_fn_attrs<'ll, 'tcx>(
// The target doesn't care; the subtarget reads our attribute.
apply_tune_cpu_attr(cx, llfn);
let mut function_features = codegen_fn_attrs
.target_features
let function_features =
codegen_fn_attrs.target_features.iter().map(|f| f.as_str()).collect::<Vec<&str>>();
if let Some(f) = llvm_util::check_tied_features(
cx.tcx.sess,
&function_features.iter().map(|f| (*f, true)).collect(),
) {
let span = cx
.tcx
.get_attrs(instance.def_id())
.iter()
.find(|a| a.has_name(rustc_span::sym::target_feature))
.map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
let msg = format!(
"the target features {} must all be either enabled or disabled together",
f.join(", ")
);
let mut err = cx.tcx.sess.struct_span_err(span, &msg);
err.help("add the missing features in a `target_feature` attribute");
err.emit();
return;
}
let mut function_features = function_features
.iter()
.flat_map(|f| {
let feature = f.as_str();
llvm_util::to_llvm_feature(cx.tcx.sess, feature)
.flat_map(|feat| {
llvm_util::to_llvm_feature(cx.tcx.sess, feat)
.into_iter()
.map(|f| format!("+{}", f))
.collect::<Vec<String>>()

View file

@ -2,8 +2,8 @@ use crate::back::write::create_informational_target_machine;
use crate::{llvm, llvm_util};
use libc::c_int;
use libloading::Library;
use rustc_codegen_ssa::target_features::supported_target_features;
use rustc_data_structures::fx::FxHashSet;
use rustc_codegen_ssa::target_features::{supported_target_features, tied_target_features};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_fs_util::path_to_c_string;
use rustc_middle::bug;
use rustc_session::config::PrintRequest;
@ -191,10 +191,30 @@ pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> Vec<&'a str> {
("aarch64", "frintts") => vec!["fptoint"],
("aarch64", "fcma") => vec!["complxnum"],
("aarch64", "pmuv3") => vec!["perfmon"],
("aarch64", "paca") => vec!["pauth"],
("aarch64", "pacg") => vec!["pauth"],
(_, s) => vec![s],
}
}
// Given a map from target_features to whether they are enabled or disabled,
// ensure only valid combinations are allowed.
pub fn check_tied_features(
sess: &Session,
features: &FxHashMap<&str, bool>,
) -> Option<&'static [&'static str]> {
for tied in tied_target_features(sess) {
// Tied features must be set to the same value, or not set at all
let mut tied_iter = tied.iter();
let enabled = features.get(tied_iter.next().unwrap());
if tied_iter.any(|f| enabled != features.get(f)) {
return Some(tied);
}
}
None
}
pub fn target_features(sess: &Session) -> Vec<Symbol> {
let target_machine = create_informational_target_machine(sess);
supported_target_features(sess)
@ -395,15 +415,19 @@ pub fn llvm_global_features(sess: &Session) -> Vec<String> {
Some(_) | None => {}
};
fn strip(s: &str) -> &str {
s.strip_prefix(&['+', '-']).unwrap_or(s)
}
let filter = |s: &str| {
if s.is_empty() {
return vec![];
}
let feature = if s.starts_with('+') || s.starts_with('-') {
&s[1..]
} else {
let feature = strip(s);
if feature == s {
return vec![s.to_string()];
};
}
// Rustc-specific feature requests like `+crt-static` or `-crt-static`
// are not passed down to LLVM.
if RUSTC_SPECIFIC_FEATURES.contains(&feature) {
@ -420,8 +444,17 @@ pub fn llvm_global_features(sess: &Session) -> Vec<String> {
features.extend(sess.target.features.split(',').flat_map(&filter));
// -Ctarget-features
features.extend(sess.opts.cg.target_feature.split(',').flat_map(&filter));
let feats: Vec<&str> = sess.opts.cg.target_feature.split(',').collect();
// LLVM enables based on the last occurence of a feature
if let Some(f) =
check_tied_features(sess, &feats.iter().map(|f| (strip(f), !f.starts_with("-"))).collect())
{
sess.err(&format!(
"Target features {} must all be enabled or disabled together",
f.join(", ")
));
}
features.extend(feats.iter().flat_map(|&f| filter(f)));
features
}

View file

@ -74,8 +74,10 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("ssbs", Some(sym::aarch64_target_feature)),
// FEAT_SB
("sb", Some(sym::aarch64_target_feature)),
// FEAT_PAUTH
("pauth", Some(sym::aarch64_target_feature)),
// FEAT_PAUTH (address authentication)
("paca", Some(sym::aarch64_target_feature)),
// FEAT_PAUTH (generic authentication)
("pacg", Some(sym::aarch64_target_feature)),
// FEAT_DPB
("dpb", Some(sym::aarch64_target_feature)),
// FEAT_DPB2
@ -137,6 +139,8 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("v8.7a", Some(sym::aarch64_target_feature)),
];
const AARCH64_TIED_FEATURES: &[&[&str]] = &[&["paca", "pacg"]];
const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("adx", Some(sym::adx_target_feature)),
("aes", None),
@ -256,6 +260,13 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt
}
}
pub fn tied_target_features(sess: &Session) -> &'static [&'static [&'static str]] {
match &*sess.target.arch {
"aarch64" => AARCH64_TIED_FEATURES,
_ => &[],
}
}
pub(crate) fn provide(providers: &mut Providers) {
providers.supported_target_features = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);

View file

@ -8,7 +8,7 @@ use super::{ForeignItem, ImplItem, Item, TraitItem};
///
/// 1. **Shallow visit**: Get a simple callback for every item (or item-like thing) in the HIR.
/// - Example: find all items with a `#[foo]` attribute on them.
/// - How: Implement `ItemLikeVisitor` and call `tcx.hir().krate().visit_all_item_likes()`.
/// - How: Implement `ItemLikeVisitor` and call `tcx.hir().visit_all_item_likes()`.
/// - Pro: Efficient; just walks the lists of item-like things, not the nodes themselves.
/// - Con: Don't get information about nesting
/// - Con: Don't have methods for specific bits of HIR, like "on
@ -19,9 +19,9 @@ use super::{ForeignItem, ImplItem, Item, TraitItem};
/// - Example: Examine each expression to look for its type and do some check or other.
/// - How: Implement `intravisit::Visitor` and override the `nested_visit_map()` method
/// to return `NestedVisitorMap::OnlyBodies` and use
/// `tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor())`. Within
/// your `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget
/// to invoke `intravisit::walk_expr()` to keep walking the subparts).
/// `tcx.hir().visit_all_item_likes(&mut visitor.as_deep_visitor())`. Within your
/// `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke
/// `intravisit::walk_expr()` to keep walking the subparts).
/// - Pro: Visitor methods for any kind of HIR node, not just item-like things.
/// - Pro: Integrates well into dependency tracking.
/// - Con: Don't get information about nesting between items

View file

@ -286,8 +286,7 @@ pub fn configure_and_expand(
rustc_builtin_macros::register_builtin_macros(resolver);
krate = sess.time("crate_injection", || {
let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| Symbol::intern(s));
rustc_builtin_macros::standard_library_imports::inject(krate, resolver, sess, alt_std_name)
rustc_builtin_macros::standard_library_imports::inject(krate, resolver, sess)
});
util::check_attr_crate_type(sess, &krate.attrs, &mut resolver.lint_buffer());

View file

@ -118,7 +118,7 @@ fn get_stack_size() -> Option<usize> {
/// Like a `thread::Builder::spawn` followed by a `join()`, but avoids the need
/// for `'static` bounds.
#[cfg(not(parallel_compiler))]
pub fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f: F) -> R {
fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f: F) -> R {
// SAFETY: join() is called immediately, so any closure captures are still
// alive.
match unsafe { cfg.spawn_unchecked(f) }.unwrap().join() {
@ -379,7 +379,7 @@ fn sysroot_candidates() -> Vec<PathBuf> {
}
}
pub fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> MakeBackendFn {
fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> MakeBackendFn {
// For now we only allow this function to be called once as it'll dlopen a
// few things, which seems to work best if we only do that once. In
// general this assertion never trips due to the once guard in `get_codegen_backend`,

View file

@ -453,28 +453,28 @@ impl<'a> Resolver<'a> {
// edit:
// only do this if the const and usage of the non-constant value are on the same line
// the further the two are apart, the higher the chance of the suggestion being wrong
// also make sure that the pos for the suggestion is not 0 (ICE #90878)
let sp =
self.session.source_map().span_extend_to_prev_str(ident.span, current, true);
let sp = self
.session
.source_map()
.span_extend_to_prev_str(ident.span, current, true, false);
let pos_for_suggestion = sp.lo().0.saturating_sub(current.len() as u32);
if sp.lo().0 == 0
|| pos_for_suggestion == 0
|| self.session.source_map().is_multiline(sp)
{
err.span_label(ident.span, &format!("this would need to be a `{}`", sugg));
} else {
let sp = sp.with_lo(BytePos(pos_for_suggestion));
err.span_suggestion(
sp,
&format!("consider using `{}` instead of `{}`", sugg, current),
format!("{} {}", sugg, ident),
Applicability::MaybeIncorrect,
);
err.span_label(span, "non-constant value");
match sp {
Some(sp) if !self.session.source_map().is_multiline(sp) => {
let sp = sp.with_lo(BytePos(sp.lo().0 - (current.len() as u32)));
err.span_suggestion(
sp,
&format!("consider using `{}` instead of `{}`", sugg, current),
format!("{} {}", sugg, ident),
Applicability::MaybeIncorrect,
);
err.span_label(span, "non-constant value");
}
_ => {
err.span_label(ident.span, &format!("this would need to be a `{}`", sugg));
}
}
err
}
ResolutionError::BindingShadowsSomethingUnacceptable {

View file

@ -770,7 +770,6 @@ impl Default for Options {
externs: Externs(BTreeMap::new()),
extern_dep_specs: ExternDepSpecs(BTreeMap::new()),
crate_name: None,
alt_std_name: None,
libs: Vec::new(),
unstable_features: UnstableFeatures::Disallow,
debug_assertions: true,
@ -2382,7 +2381,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()),
extern_dep_specs,
crate_name,
alt_std_name: None,
libs,
debug_assertions,
actually_rustdoc: false,

View file

@ -184,10 +184,6 @@ top_level_options!(
externs: Externs [UNTRACKED],
extern_dep_specs: ExternDepSpecs [UNTRACKED],
crate_name: Option<String> [TRACKED],
/// An optional name to use as the crate for std during std injection,
/// written `extern crate name as std`. Defaults to `std`. Used by
/// out-of-tree drivers.
alt_std_name: Option<String> [TRACKED],
/// Indicates how the compiler should treat unstable features.
unstable_features: UnstableFeatures [TRACKED],

View file

@ -629,26 +629,41 @@ impl SourceMap {
}
/// Extends the given `Span` to just after the previous occurrence of `pat` when surrounded by
/// whitespace. Returns the same span if no character could be found or if an error occurred
/// while retrieving the code snippet.
pub fn span_extend_to_prev_str(&self, sp: Span, pat: &str, accept_newlines: bool) -> Span {
/// whitespace. Returns None if the pattern could not be found or if an error occurred while
/// retrieving the code snippet.
pub fn span_extend_to_prev_str(
&self,
sp: Span,
pat: &str,
accept_newlines: bool,
include_whitespace: bool,
) -> Option<Span> {
// assure that the pattern is delimited, to avoid the following
// fn my_fn()
// ^^^^ returned span without the check
// ---------- correct span
let prev_source = self.span_to_prev_source(sp).ok()?;
for ws in &[" ", "\t", "\n"] {
let pat = pat.to_owned() + ws;
if let Ok(prev_source) = self.span_to_prev_source(sp) {
let prev_source = prev_source.rsplit(&pat).next().unwrap_or("").trim_start();
if prev_source.is_empty() && sp.lo().0 != 0 {
return sp.with_lo(BytePos(sp.lo().0 - 1));
} else if accept_newlines || !prev_source.contains('\n') {
return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32));
if let Some(pat_pos) = prev_source.rfind(&pat) {
let just_after_pat_pos = pat_pos + pat.len() - 1;
let just_after_pat_plus_ws = if include_whitespace {
just_after_pat_pos
+ prev_source[just_after_pat_pos..]
.find(|c: char| !c.is_whitespace())
.unwrap_or(0)
} else {
just_after_pat_pos
};
let len = prev_source.len() - just_after_pat_plus_ws;
let prev_source = &prev_source[just_after_pat_plus_ws..];
if accept_newlines || !prev_source.trim_start().contains('\n') {
return Some(sp.with_lo(BytePos(sp.lo().0 - len as u32)));
}
}
}
sp
None
}
/// Returns the source snippet as `String` after the given `Span`.
@ -927,7 +942,7 @@ impl SourceMap {
}
pub fn generate_fn_name_span(&self, span: Span) -> Option<Span> {
let prev_span = self.span_extend_to_prev_str(span, "fn", true);
let prev_span = self.span_extend_to_prev_str(span, "fn", true, true).unwrap_or(span);
if let Ok(snippet) = self.span_to_snippet(prev_span) {
debug!(
"generate_fn_name_span: span={:?}, prev_span={:?}, snippet={:?}",
@ -968,8 +983,7 @@ impl SourceMap {
pub fn generate_local_type_param_snippet(&self, span: Span) -> Option<(Span, String)> {
// Try to extend the span to the previous "fn" keyword to retrieve the function
// signature.
let sugg_span = self.span_extend_to_prev_str(span, "fn", false);
if sugg_span != span {
if let Some(sugg_span) = self.span_extend_to_prev_str(span, "fn", false, true) {
if let Ok(snippet) = self.span_to_snippet(sugg_span) {
// Consume the function name.
let mut offset = snippet

View file

@ -1819,7 +1819,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
[] => {}
[trait_info] => {
let msg = format!(
"the trait `{}` defines an item `{}`, but is explicitely unimplemented",
"the trait `{}` defines an item `{}`, but is explicitly unimplemented",
self.tcx.def_path_str(trait_info.def_id),
item_name
);
@ -1827,7 +1827,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
trait_infos => {
let mut msg = format!(
"the following traits define an item `{}`, but are explicitely unimplemented:",
"the following traits define an item `{}`, but are explicitly unimplemented:",
item_name
);
for trait_info in trait_infos {

View file

@ -23,6 +23,11 @@ use crate::sys::os as os_imp;
/// Returns the current working directory as a [`PathBuf`].
///
/// # Platform-specific behavior
///
/// This function currently corresponds to the `getcwd` function on Unix
/// and the `GetCurrentDirectoryW` function on Windows.
///
/// # Errors
///
/// Returns an [`Err`] if the current working directory value is invalid.
@ -49,6 +54,11 @@ pub fn current_dir() -> io::Result<PathBuf> {
/// Changes the current working directory to the specified path.
///
/// # Platform-specific behavior
///
/// This function currently corresponds to the `chdir` function on Unix
/// and the `SetCurrentDirectoryW` function on Windows.
///
/// Returns an [`Err`] if the operation fails.
///
/// # Examples

View file

@ -296,12 +296,11 @@ pub enum ErrorKind {
/// The filesystem does not support making so many hardlinks to the same file.
#[unstable(feature = "io_error_more", issue = "86442")]
TooManyLinks,
/// Filename too long.
/// A filename was invalid.
///
/// The limit might be from the underlying filesystem or API, or an administratively imposed
/// resource limit.
/// This error can also cause if it exceeded the filename length limit.
#[unstable(feature = "io_error_more", issue = "86442")]
FilenameTooLong,
InvalidFilename,
/// Program argument list too long.
///
/// When trying to run an external program, a system or process limit on the size of the
@ -382,12 +381,12 @@ impl ErrorKind {
DirectoryNotEmpty => "directory not empty",
ExecutableFileBusy => "executable file busy",
FileTooLarge => "file too large",
FilenameTooLong => "filename too long",
FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)",
FilesystemQuotaExceeded => "filesystem quota exceeded",
HostUnreachable => "host unreachable",
Interrupted => "operation interrupted",
InvalidData => "invalid data",
InvalidFilename => "invalid filename",
InvalidInput => "invalid input parameter",
IsADirectory => "is a directory",
NetworkDown => "network down",

View file

@ -315,7 +315,7 @@ fn kind_from_prim(ek: u32) -> Option<ErrorKind> {
Deadlock,
CrossesDevices,
TooManyLinks,
FilenameTooLong,
InvalidFilename,
ArgumentListTooLong,
Interrupted,
Other,

View file

@ -200,6 +200,22 @@ pub trait AsFd {
fn as_fd(&self) -> BorrowedFd<'_>;
}
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsFd> AsFd for &T {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
T::as_fd(self)
}
}
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsFd> AsFd for &mut T {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
T::as_fd(self)
}
}
#[unstable(feature = "io_safety", issue = "87074")]
impl AsFd for BorrowedFd<'_> {
#[inline]

View file

@ -966,7 +966,7 @@ pub fn chown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::
///
/// fn main() -> std::io::Result<()> {
/// let f = std::fs::File::open("/file")?;
/// fs::fchown(f, Some(0), Some(0))?;
/// fs::fchown(&f, Some(0), Some(0))?;
/// Ok(())
/// }
/// ```

View file

@ -316,6 +316,22 @@ pub trait AsHandle {
fn as_handle(&self) -> BorrowedHandle<'_>;
}
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsHandle> AsHandle for &T {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
T::as_handle(self)
}
}
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsHandle> AsHandle for &mut T {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
T::as_handle(self)
}
}
impl AsHandle for BorrowedHandle<'_> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {

View file

@ -210,6 +210,22 @@ pub trait AsSocket {
fn as_socket(&self) -> BorrowedSocket<'_>;
}
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsSocket> AsSocket for &T {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
T::as_socket(self)
}
}
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsSocket> AsSocket for &mut T {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
T::as_socket(self)
}
}
impl AsSocket for BorrowedSocket<'_> {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {

View file

@ -159,7 +159,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
libc::ENOSPC => StorageFull,
libc::ENOSYS => Unsupported,
libc::EMLINK => TooManyLinks,
libc::ENAMETOOLONG => FilenameTooLong,
libc::ENAMETOOLONG => InvalidFilename,
libc::ENETDOWN => NetworkDown,
libc::ENETUNREACH => NetworkUnreachable,
libc::ENOTCONN => NotConnected,

View file

@ -71,6 +71,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
c::ERROR_FILE_NOT_FOUND => return NotFound,
c::ERROR_PATH_NOT_FOUND => return NotFound,
c::ERROR_NO_DATA => return BrokenPipe,
c::ERROR_INVALID_NAME => return InvalidFilename,
c::ERROR_INVALID_PARAMETER => return InvalidInput,
c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory,
c::ERROR_SEM_TIMEOUT
@ -104,7 +105,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
c::ERROR_POSSIBLE_DEADLOCK => return Deadlock,
c::ERROR_NOT_SAME_DEVICE => return CrossesDevices,
c::ERROR_TOO_MANY_LINKS => return TooManyLinks,
c::ERROR_FILENAME_EXCED_RANGE => return FilenameTooLong,
c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename,
_ => {}
}

View file

@ -0,0 +1,21 @@
// ignore-tidy-linelength
// @count dyn.json "$.index[*][?(@.name=='dyn')].inner.items" 1
// @set sync_int_gen = - "$.index[*][?(@.name=='SyncIntGen')].id"
// @is - "$.index[*][?(@.name=='dyn')].inner.items[0]" $sync_int_gen
// @is - "$.index[*][?(@.name=='SyncIntGen')].kind" \"typedef\"
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.generics" '{"params": [], "where_predicates": []}'
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.kind" \"resolved_path\"
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.name" \"Box\"
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.bindings" []
// @count - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args" 1
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"resolved_path\"
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"resolved_path\"
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.name" \"Fn\"
// @count - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[*]" 3
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[0].trait_bound.trait.inner.name" \"Send\"
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[1].trait_bound.trait.inner.name" \"Sync\"
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[2]" "{\"outlives\": \"'static\"}"
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}'
pub type SyncIntGen = Box<dyn Fn() -> i32 + Send + Sync + 'static>;

View file

@ -0,0 +1,28 @@
// ignore-tidy-linelength
// @is fn_lifetime.json "$.index[*][?(@.name=='GenericFn')].kind" \"typedef\"
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*]" 1
// @is - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].name" \"\'a\"
// @has - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime"
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime.outlives[*]" 0
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.where_predicates[*]" 0
// @is - "$.index[*][?(@.name=='GenericFn')].inner.type.kind" \"function_pointer\"
// @count - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.generic_params[*]" 0
// @count - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.inputs[*]" 1
// @is - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.inputs[*][1].inner.lifetime" \"\'a\"
// @is - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.output.inner.lifetime" \"\'a\"
pub type GenericFn<'a> = fn(&'a i32) -> &'a i32;
// @is fn_lifetime.json "$.index[*][?(@.name=='ForAll')].kind" \"typedef\"
// @count - "$.index[*][?(@.name=='ForAll')].inner.generics.params[*]" 0
// @count - "$.index[*][?(@.name=='ForAll')].inner.generics.where_predicates[*]" 0
// @count - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*]" 1
// @is - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].name" \"\'a\"
// @has - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].kind.lifetime"
// @count - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].kind.lifetime.outlives[*]" 0
// @count - "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.inputs[*]" 1
// @is - "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.inputs[*][1].inner.lifetime" \"\'a\"
// @is - "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.output.inner.lifetime" \"\'a\"
pub type ForAll = for<'a> fn(&'a i32) -> &'a i32;

View file

@ -0,0 +1,33 @@
// ignore-tidy-linelength
// @set result = generic_default.json "$.index[*][?(@.name=='Result')].id"
pub enum Result<T, E> {
Ok(T),
Err(E),
}
// @set my_error = - "$.index[*][?(@.name=='MyError')].id"
pub struct MyError {}
// @is - "$.index[*][?(@.name=='MyResult')].kind" \"typedef\"
// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.where_predicates[*]" 0
// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.params[*]" 2
// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].name" \"T\"
// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].name" \"E\"
// @has - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type"
// @has - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type"
// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type.bounds[*]" 0
// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.bounds[*]" 0
// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type.default" null
// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.kind" \"resolved_path\"
// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.inner.id" $my_error
// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.inner.name" \"MyError\"
// @is - "$.index[*][?(@.name=='MyResult')].inner.type.kind" \"resolved_path\"
// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.id" $result
// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.name" \"Result\"
// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.bindings" []
// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"generic\"
// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[1].type.kind" \"generic\"
// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[0].type.inner" \"T\"
// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[1].type.inner" \"E\"
pub type MyResult<T, E = MyError> = Result<T, E>;

View file

@ -382,7 +382,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:39:37
|
LL | let mut foo = 0;
| ---------- help: consider using `const` instead of `let`: `const foo`
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{}", options(), const foo);
| ^^^ non-constant value
@ -391,7 +391,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:48:44
|
LL | let mut foo = 0;
| ---------- help: consider using `const` instead of `let`: `const foo`
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{}", clobber_abi("C"), const foo);
| ^^^ non-constant value
@ -400,7 +400,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:55:31
|
LL | let mut foo = 0;
| ---------- help: consider using `const` instead of `let`: `const foo`
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{a}", a = const foo, a = const bar);
| ^^^ non-constant value
@ -409,7 +409,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:55:46
|
LL | let mut bar = 0;
| ---------- help: consider using `const` instead of `let`: `const bar`
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{a}", a = const foo, a = const bar);
| ^^^ non-constant value
@ -418,7 +418,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:62:45
|
LL | let mut bar = 0;
| ---------- help: consider using `const` instead of `let`: `const bar`
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{a}", in("x0") foo, a = const bar);
| ^^^ non-constant value
@ -427,7 +427,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:65:45
|
LL | let mut bar = 0;
| ---------- help: consider using `const` instead of `let`: `const bar`
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{a}", in("x0") foo, a = const bar);
| ^^^ non-constant value
@ -436,7 +436,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:68:41
|
LL | let mut bar = 0;
| ---------- help: consider using `const` instead of `let`: `const bar`
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{1}", in("x0") foo, const bar);
| ^^^ non-constant value

View file

@ -0,0 +1,20 @@
// compile-flags: --target armv7-unknown-linux-gnueabihf
// needs-llvm-components: arm
#![feature(no_core, lang_items, rustc_attrs)]
#![no_core]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[lang = "sized"]
trait Sized {}
fn main() {
unsafe {
asm!("", out("d0") _, out("d1") _);
asm!("", out("d0") _, out("s1") _);
//~^ ERROR register `s1` conflicts with register `d0`
}
}

View file

@ -0,0 +1,10 @@
error: register `s1` conflicts with register `d0`
--> $DIR/reg-conflict.rs:17:31
|
LL | asm!("", out("d0") _, out("s1") _);
| ----------- ^^^^^^^^^^^ register `s1`
| |
| register `d0`
error: aborting due to previous error

View file

@ -394,7 +394,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:39:37
|
LL | let mut foo = 0;
| ---------- help: consider using `const` instead of `let`: `const foo`
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{}", options(), const foo);
| ^^^ non-constant value
@ -403,7 +403,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:50:44
|
LL | let mut foo = 0;
| ---------- help: consider using `const` instead of `let`: `const foo`
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{}", clobber_abi("C"), const foo);
| ^^^ non-constant value
@ -412,7 +412,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:57:31
|
LL | let mut foo = 0;
| ---------- help: consider using `const` instead of `let`: `const foo`
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{a}", a = const foo, a = const bar);
| ^^^ non-constant value
@ -421,7 +421,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:57:46
|
LL | let mut bar = 0;
| ---------- help: consider using `const` instead of `let`: `const bar`
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{a}", a = const foo, a = const bar);
| ^^^ non-constant value
@ -430,7 +430,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:64:46
|
LL | let mut bar = 0;
| ---------- help: consider using `const` instead of `let`: `const bar`
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{a}", in("eax") foo, a = const bar);
| ^^^ non-constant value
@ -439,7 +439,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:67:46
|
LL | let mut bar = 0;
| ---------- help: consider using `const` instead of `let`: `const bar`
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{a}", in("eax") foo, a = const bar);
| ^^^ non-constant value
@ -448,7 +448,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:70:42
|
LL | let mut bar = 0;
| ---------- help: consider using `const` instead of `let`: `const bar`
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{1}", in("eax") foo, const bar);
| ^^^ non-constant value

View file

@ -0,0 +1,21 @@
// Regression test for issue #91560.
// run-rustfix
#![allow(unused,non_upper_case_globals)]
fn foo() {
const length: usize = 2;
//~^ HELP: consider using `const`
let arr = [0; length];
//~^ ERROR: attempt to use a non-constant value in a constant [E0435]
}
fn bar() {
const length: usize = 2;
//~^ HELP: consider using `const`
let arr = [0; length];
//~^ ERROR: attempt to use a non-constant value in a constant [E0435]
}
fn main() {}

View file

@ -0,0 +1,21 @@
// Regression test for issue #91560.
// run-rustfix
#![allow(unused,non_upper_case_globals)]
fn foo() {
let mut length: usize = 2;
//~^ HELP: consider using `const`
let arr = [0; length];
//~^ ERROR: attempt to use a non-constant value in a constant [E0435]
}
fn bar() {
let length: usize = 2;
//~^ HELP: consider using `const`
let arr = [0; length];
//~^ ERROR: attempt to use a non-constant value in a constant [E0435]
}
fn main() {}

View file

@ -0,0 +1,21 @@
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/issue-91560.rs:10:19
|
LL | let mut length: usize = 2;
| -------------- help: consider using `const` instead of `let`: `const length`
LL |
LL | let arr = [0; length];
| ^^^^^^ non-constant value
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/issue-91560.rs:17:19
|
LL | let length: usize = 2;
| ------------ help: consider using `const` instead of `let`: `const length`
LL |
LL | let arr = [0; length];
| ^^^^^^ non-constant value
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0435`.

View file

@ -0,0 +1,4 @@
error: Target features paca, pacg must all be enabled or disabled together
error: aborting due to previous error

View file

@ -0,0 +1,9 @@
// only-aarch64
// revisions: one two three four
//[one] compile-flags: -C target-feature=+paca
//[two] compile-flags: -C target-feature=-pacg,+pacg
//[three] compile-flags: -C target-feature=+paca,+pacg,-paca
//[four] check-pass
//[four] compile-flags: -C target-feature=-paca,+pacg -C target-feature=+paca
fn main() {}

View file

@ -0,0 +1,4 @@
error: Target features paca, pacg must all be enabled or disabled together
error: aborting due to previous error

View file

@ -0,0 +1,4 @@
error: Target features paca, pacg must all be enabled or disabled together
error: aborting due to previous error

View file

@ -0,0 +1,29 @@
// only-aarch64
// build-fail
#![feature(aarch64_target_feature, target_feature_11)]
fn main() {
#[target_feature(enable = "pacg")]
//~^ ERROR must all be either enabled or disabled together
unsafe fn inner() {}
unsafe {
foo();
bar();
baz();
inner();
}
}
#[target_feature(enable = "paca")]
//~^ ERROR must all be either enabled or disabled together
unsafe fn foo() {}
#[target_feature(enable = "paca,pacg")]
unsafe fn bar() {}
#[target_feature(enable = "paca")]
#[target_feature(enable = "pacg")]
unsafe fn baz() {}

View file

@ -0,0 +1,18 @@
error: the target features paca, pacg must all be either enabled or disabled together
--> $DIR/tied-features.rs:7:5
|
LL | #[target_feature(enable = "pacg")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add the missing features in a `target_feature` attribute
error: the target features paca, pacg must all be either enabled or disabled together
--> $DIR/tied-features.rs:19:1
|
LL | #[target_feature(enable = "paca")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add the missing features in a `target_feature` attribute
error: aborting due to 2 previous errors

View file

@ -34,20 +34,20 @@ fn main() {
Qux.clone();
//~^ ERROR no method named `clone` found for struct `Qux`
//~| NOTE method not found in `Qux`
//~| NOTE `Clone` defines an item `clone`, but is explicitely unimplemented
//~| NOTE `Clone` defines an item `clone`, but is explicitly unimplemented
0_u32.bar();
//~^ ERROR no method named `bar` found for type `u32`
//~| NOTE method not found in `u32`
//~| NOTE `Bar` defines an item `bar`, but is explicitely unimplemented
//~| NOTE `Bar` defines an item `bar`, but is explicitly unimplemented
Qux.foo();
//~^ ERROR no method named `foo` found for struct `Qux`
//~| NOTE method not found in `Qux`
//~| NOTE the following traits define an item `foo`, but are explicitely unimplemented
//~| NOTE the following traits define an item `foo`, but are explicitly unimplemented
0_u32.foo();
//~^ ERROR no method named `foo` found for type `u32`
//~| NOTE method not found in `u32`
//~| NOTE `FooBar` defines an item `foo`, but is explicitely unimplemented
//~| NOTE `FooBar` defines an item `foo`, but is explicitly unimplemented
}

View file

@ -8,7 +8,7 @@ LL | Qux.clone();
| ^^^^^ method not found in `Qux`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the trait `Clone` defines an item `clone`, but is explicitely unimplemented
= note: the trait `Clone` defines an item `clone`, but is explicitly unimplemented
error[E0599]: no method named `bar` found for type `u32` in the current scope
--> $DIR/explicitly-unimplemented-error-message.rs:39:11
@ -17,7 +17,7 @@ LL | 0_u32.bar();
| ^^^ method not found in `u32`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the trait `Bar` defines an item `bar`, but is explicitely unimplemented
= note: the trait `Bar` defines an item `bar`, but is explicitly unimplemented
error[E0599]: no method named `foo` found for struct `Qux` in the current scope
--> $DIR/explicitly-unimplemented-error-message.rs:44:9
@ -29,7 +29,7 @@ LL | Qux.foo();
| ^^^ method not found in `Qux`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following traits define an item `foo`, but are explicitely unimplemented:
= note: the following traits define an item `foo`, but are explicitly unimplemented:
Foo
FooBar
@ -45,7 +45,7 @@ note: `Foo` defines an item `foo`, perhaps you need to implement it
|
LL | trait Foo {
| ^^^^^^^^^
= note: the trait `FooBar` defines an item `foo`, but is explicitely unimplemented
= note: the trait `FooBar` defines an item `foo`, but is explicitly unimplemented
error: aborting due to 4 previous errors

View file

@ -231,7 +231,21 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
let val = cache.get_value(&command.args[0])?;
let results = select(&val, &command.args[1]).unwrap();
results.len() == expected
let eq = results.len() == expected;
if !command.negated && !eq {
return Err(CkError::FailedCheck(
format!(
"`{}` matched to `{:?}` with length {}, but expected length {}",
&command.args[1],
results,
results.len(),
expected
),
command,
));
} else {
eq
}
}
CommandKind::Is => {
// @has <path> <jsonpath> <value> = check *exactly one* item matched by path, and it equals value
@ -317,6 +331,6 @@ fn string_to_value<'a>(s: &str, cache: &'a Cache) -> Cow<'a, Value> {
panic!("No variable: `{}`. Current state: `{:?}`", &s[1..], cache.variables)
}))
} else {
Cow::Owned(serde_json::from_str(s).unwrap())
Cow::Owned(serde_json::from_str(s).expect(&format!("Cannot convert `{}` to json", s)))
}
}