Auto merge of #72716 - Dylan-DPC:rollup-wdj97ab, r=Dylan-DPC
Rollup of 12 pull requests Successful merges: - #72239 (Implement PartialOrd and Ord for SocketAddr*) - #72466 (Stabilize str_strip feature) - #72605 (Add working example for E0617 explanation) - #72636 (Cleanup `Resolver::<clone|into>_outputs` methods) - #72645 (Add myself to .mailmap) - #72667 (expand unaligned_references test) - #72670 (Fix incorrect comment in generator test) - #72674 (Clippy should always build) - #72682 (Add test for #66930) - #72695 (update data layout for illumos x86) - #72697 (Remove rustc-ux-guidelines) - #72702 (rustc_lint: Remove `unused_crate_dependencies` from the `unused` group) Failed merges: r? @ghost
This commit is contained in:
commit
255c0338dc
25 changed files with 248 additions and 225 deletions
2
.mailmap
2
.mailmap
|
@ -70,6 +70,8 @@ David Manescu <david.manescu@gmail.com> <dman2626@uni.sydney.edu.au>
|
|||
David Ross <daboross@daboross.net>
|
||||
Derek Chiang <derekchiang93@gmail.com> Derek Chiang (Enchi Jiang) <derekchiang93@gmail.com>
|
||||
Diggory Hardy <diggory.hardy@gmail.com> Diggory Hardy <github@dhardy.name>
|
||||
Donough Liu <ldm2993593805@163.com> <donoughliu@gmail.com>
|
||||
Donough Liu <ldm2993593805@163.com> DingMing Liu <liudingming@bupt.edu.cn>
|
||||
Dustin Bensing <dustin.bensing@googlemail.com>
|
||||
Dylan Braithwaite <dylanbraithwaite1@gmail.com> <mail@dylanb.me>
|
||||
Dzmitry Malyshau <kvarkus@gmail.com>
|
||||
|
|
|
@ -516,45 +516,37 @@ impl Step for Clippy {
|
|||
let host = self.host;
|
||||
let compiler = builder.compiler(stage, host);
|
||||
|
||||
let clippy = builder.ensure(tool::Clippy {
|
||||
let clippy = builder
|
||||
.ensure(tool::Clippy { compiler, target: self.host, extra_features: Vec::new() })
|
||||
.expect("in-tree tool");
|
||||
let mut cargo = tool::prepare_tool_cargo(
|
||||
builder,
|
||||
compiler,
|
||||
target: self.host,
|
||||
extra_features: Vec::new(),
|
||||
});
|
||||
if let Some(clippy) = clippy {
|
||||
let mut cargo = tool::prepare_tool_cargo(
|
||||
builder,
|
||||
compiler,
|
||||
Mode::ToolRustc,
|
||||
host,
|
||||
"test",
|
||||
"src/tools/clippy",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
);
|
||||
Mode::ToolRustc,
|
||||
host,
|
||||
"test",
|
||||
"src/tools/clippy",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
);
|
||||
|
||||
// clippy tests need to know about the stage sysroot
|
||||
cargo.env("SYSROOT", builder.sysroot(compiler));
|
||||
cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
|
||||
cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
|
||||
let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir());
|
||||
let target_libs = builder
|
||||
.stage_out(compiler, Mode::ToolRustc)
|
||||
.join(&self.host)
|
||||
.join(builder.cargo_dir());
|
||||
cargo.env("HOST_LIBS", host_libs);
|
||||
cargo.env("TARGET_LIBS", target_libs);
|
||||
// clippy tests need to find the driver
|
||||
cargo.env("CLIPPY_DRIVER_PATH", clippy);
|
||||
// clippy tests need to know about the stage sysroot
|
||||
cargo.env("SYSROOT", builder.sysroot(compiler));
|
||||
cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
|
||||
cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
|
||||
let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir());
|
||||
let target_libs =
|
||||
builder.stage_out(compiler, Mode::ToolRustc).join(&self.host).join(builder.cargo_dir());
|
||||
cargo.env("HOST_LIBS", host_libs);
|
||||
cargo.env("TARGET_LIBS", target_libs);
|
||||
// clippy tests need to find the driver
|
||||
cargo.env("CLIPPY_DRIVER_PATH", clippy);
|
||||
|
||||
cargo.arg("--").args(builder.config.cmd.test_args());
|
||||
cargo.arg("--").args(builder.config.cmd.test_args());
|
||||
|
||||
builder.add_rustc_lib_path(compiler, &mut cargo);
|
||||
builder.add_rustc_lib_path(compiler, &mut cargo);
|
||||
|
||||
try_run(builder, &mut cargo.into());
|
||||
} else {
|
||||
eprintln!("failed to test clippy: could not build");
|
||||
}
|
||||
try_run(builder, &mut cargo.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
% Rustc UX guidelines
|
||||
|
||||
Don't forget the user. Whether human or another program, such as an IDE, a
|
||||
good user experience with the compiler goes a long way toward making developers'
|
||||
lives better. We do not want users to be baffled by compiler output or
|
||||
learn arcane patterns to compile their program.
|
||||
|
||||
## Error, Warning, Help, Note Messages
|
||||
|
||||
When the compiler detects a problem, it can emit one of the following: an error, a warning,
|
||||
a note, or a help message.
|
||||
|
||||
An `error` is emitted when the compiler detects a problem that makes it unable
|
||||
to compile the program, either because the program is invalid or the
|
||||
programmer has decided to make a specific `warning` into an error.
|
||||
|
||||
A `warning` is emitted when the compiler detects something odd about a
|
||||
program. For instance, dead code and unused `Result` values.
|
||||
|
||||
A `help` message is emitted following an `error` or `warning` to give additional
|
||||
information to the user about how to solve their problem.
|
||||
|
||||
A `note` is emitted to identify additional circumstances and parts of the code
|
||||
that caused the warning or error. For example, the borrow checker will note any
|
||||
previous conflicting borrows.
|
||||
|
||||
* Write in plain simple English. If your message, when shown on a – possibly
|
||||
small – screen (which hasn't been cleaned for a while), cannot be understood
|
||||
by a normal programmer, who just came out of bed after a night partying, it's
|
||||
too complex.
|
||||
* `Errors` and `Warnings` should not suggest how to fix the problem. A `Help`
|
||||
message should be emitted instead.
|
||||
* `Error`, `Warning`, `Note`, and `Help` messages start with a lowercase
|
||||
letter and do not end with punctuation.
|
||||
* Error messages should be succinct. Users will see these error messages many
|
||||
times, and more verbose descriptions can be viewed with the `--explain` flag.
|
||||
That said, don't make it so terse that it's hard to understand.
|
||||
* The word "illegal" is illegal. Prefer "invalid" or a more specific word
|
||||
instead.
|
||||
* Errors should document the span of code where they occur – the `span_..`
|
||||
methods allow to easily do this. Also `note` other spans that have contributed
|
||||
to the error if the span isn't too large.
|
||||
* When emitting a message with span, try to reduce the span to the smallest
|
||||
amount possible that still signifies the issue
|
||||
* Try not to emit multiple error messages for the same error. This may require
|
||||
detecting duplicates.
|
||||
* When the compiler has too little information for a specific error message,
|
||||
lobby for annotations for library code that allow adding more. For example see
|
||||
`#[on_unimplemented]`. Use these annotations when available!
|
||||
* Keep in mind that Rust's learning curve is rather steep, and that the
|
||||
compiler messages are an important learning tool.
|
||||
|
||||
## Error Explanations
|
||||
|
||||
Error explanations are long form descriptions of error messages provided with
|
||||
the compiler. They are accessible via the `--explain` flag. Each explanation
|
||||
comes with an example of how to trigger it and advice on how to fix it.
|
||||
|
||||
Please read [RFC 1567](https://github.com/rust-lang/rfcs/blob/master/text/1567-long-error-codes-explanation-normalization.md)
|
||||
for details on how to format and write long error codes.
|
||||
|
||||
* All of them are accessible [online](http://doc.rust-lang.org/error-index.html),
|
||||
which are auto-generated from rustc source code in different places:
|
||||
[librustc](https://github.com/rust-lang/rust/blob/master/src/librustc/error_codes.rs),
|
||||
[librustc_ast](https://github.com/rust-lang/rust/blob/master/src/librustc_ast/error_codes.rs),
|
||||
[librustc_borrowck](https://github.com/rust-lang/rust/blob/master/src/librustc_borrowck/error_codes.rs),
|
||||
[librustc_metadata](https://github.com/rust-lang/rust/blob/master/src/librustc_metadata/error_codes.rs),
|
||||
[librustc_mir](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/error_codes.rs),
|
||||
[librustc_passes](https://github.com/rust-lang/rust/blob/master/src/librustc_passes/error_codes.rs),
|
||||
[librustc_privacy](https://github.com/rust-lang/rust/blob/master/src/librustc_privacy/error_codes.rs),
|
||||
[librustc_resolve](https://github.com/rust-lang/rust/blob/master/src/librustc_resolve/error_codes.rs),
|
||||
[librustc_codegen_llvm](https://github.com/rust-lang/rust/blob/master/src/librustc_codegen_llvm/error_codes.rs),
|
||||
[librustc_plugin_impl](https://github.com/rust-lang/rust/blob/master/src/librustc_plugin/error_codes.rs),
|
||||
[librustc_typeck](https://github.com/rust-lang/rust/blob/master/src/librustc_typeck/error_codes.rs).
|
||||
* Explanations have full markdown support. Use it, especially to highlight
|
||||
code with backticks.
|
||||
* When talking about the compiler, call it `the compiler`, not `Rust` or
|
||||
`rustc`.
|
||||
|
||||
## Compiler Flags
|
||||
|
||||
* Flags should be orthogonal to each other. For example, if we'd have a
|
||||
json-emitting variant of multiple actions `foo` and `bar`, an additional
|
||||
--json flag is better than adding `--foo-json` and `--bar-json`.
|
||||
* Always give options a long descriptive name, if only for more
|
||||
understandable compiler scripts.
|
||||
* The `--verbose` flag is for adding verbose information to `rustc` output
|
||||
when not compiling a program. For example, using it with the `--version` flag
|
||||
gives information about the hashes of the code.
|
||||
* Experimental flags and options must be guarded behind the `-Z unstable-options` flag.
|
|
@ -4052,15 +4052,13 @@ impl str {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(str_strip)]
|
||||
///
|
||||
/// assert_eq!("foo:bar".strip_prefix("foo:"), Some("bar"));
|
||||
/// assert_eq!("foo:bar".strip_prefix("bar"), None);
|
||||
/// assert_eq!("foofoo".strip_prefix("foo"), Some("foo"));
|
||||
/// ```
|
||||
#[must_use = "this returns the remaining substring as a new slice, \
|
||||
without modifying the original"]
|
||||
#[unstable(feature = "str_strip", reason = "newly added", issue = "67302")]
|
||||
#[stable(feature = "str_strip", since = "1.45.0")]
|
||||
pub fn strip_prefix<'a, P: Pattern<'a>>(&'a self, prefix: P) -> Option<&'a str> {
|
||||
prefix.strip_prefix_of(self)
|
||||
}
|
||||
|
@ -4082,14 +4080,13 @@ impl str {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(str_strip)]
|
||||
/// assert_eq!("bar:foo".strip_suffix(":foo"), Some("bar"));
|
||||
/// assert_eq!("bar:foo".strip_suffix("bar"), None);
|
||||
/// assert_eq!("foofoo".strip_suffix("foo"), Some("foo"));
|
||||
/// ```
|
||||
#[must_use = "this returns the remaining substring as a new slice, \
|
||||
without modifying the original"]
|
||||
#[unstable(feature = "str_strip", reason = "newly added", issue = "67302")]
|
||||
#[stable(feature = "str_strip", since = "1.45.0")]
|
||||
pub fn strip_suffix<'a, P>(&'a self, suffix: P) -> Option<&'a str>
|
||||
where
|
||||
P: Pattern<'a>,
|
||||
|
|
|
@ -17,3 +17,14 @@ Certain Rust types must be cast before passing them to a variadic function,
|
|||
because of arcane ABI rules dictated by the C standard. To fix the error,
|
||||
cast the value to the type specified by the error message (which you may need
|
||||
to import from `std::os::raw`).
|
||||
|
||||
In this case, `c_double` has the same size as `f64` so we can use it directly:
|
||||
|
||||
```no_run
|
||||
# extern {
|
||||
# fn printf(c: *const i8, ...);
|
||||
# }
|
||||
unsafe {
|
||||
printf(::std::ptr::null(), 0f64); // ok!
|
||||
}
|
||||
```
|
||||
|
|
|
@ -10,7 +10,6 @@ pub use rustc_ast::ast::{CaptureBy, Movability, Mutability};
|
|||
use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_ast::node_id::NodeMap;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::source_map::{SourceMap, Spanned};
|
||||
|
@ -2664,10 +2663,6 @@ impl<ID> TraitCandidate<ID> {
|
|||
// Trait method resolution
|
||||
pub type TraitMap<ID = HirId> = NodeMap<Vec<TraitCandidate<ID>>>;
|
||||
|
||||
// Map from the NodeId of a glob import to a list of items which are actually
|
||||
// imported.
|
||||
pub type GlobMap = NodeMap<FxHashSet<Symbol>>;
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub enum Node<'hir> {
|
||||
Param(&'hir Param<'hir>),
|
||||
|
|
|
@ -276,7 +276,6 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
|
|||
UNUSED_ALLOCATION,
|
||||
UNUSED_DOC_COMMENTS,
|
||||
UNUSED_EXTERN_CRATES,
|
||||
UNUSED_CRATE_DEPENDENCIES,
|
||||
UNUSED_FEATURES,
|
||||
UNUSED_LABELS,
|
||||
UNUSED_PARENS,
|
||||
|
|
|
@ -169,7 +169,6 @@ impl<'hir> Map<'hir> {
|
|||
})
|
||||
}
|
||||
|
||||
// FIXME(eddyb) this function can and should return `LocalDefId`.
|
||||
#[inline]
|
||||
pub fn local_def_id(&self, hir_id: HirId) -> LocalDefId {
|
||||
self.opt_local_def_id(hir_id).unwrap_or_else(|| {
|
||||
|
@ -192,11 +191,6 @@ impl<'hir> Map<'hir> {
|
|||
self.tcx.definitions.opt_local_def_id(node)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
|
||||
self.tcx.definitions.as_local_node_id(def_id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_local_hir_id(&self, def_id: LocalDefId) -> HirId {
|
||||
self.tcx.definitions.as_local_hir_id(def_id)
|
||||
|
|
|
@ -973,7 +973,9 @@ rustc_queries! {
|
|||
desc { "fetching what a crate is named" }
|
||||
}
|
||||
query item_children(_: DefId) -> &'tcx [Export<hir::HirId>] {}
|
||||
query extern_mod_stmt_cnum(_: DefId) -> Option<CrateNum> {}
|
||||
query extern_mod_stmt_cnum(_: LocalDefId) -> Option<CrateNum> {
|
||||
desc { "fetching extern module statement" }
|
||||
}
|
||||
|
||||
query get_lib_features(_: CrateNum) -> LibFeatures {
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
|
@ -1040,7 +1042,7 @@ rustc_queries! {
|
|||
desc { |tcx| "maybe_unused_trait_import for `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
||||
}
|
||||
query maybe_unused_extern_crates(_: CrateNum)
|
||||
-> &'tcx [(DefId, Span)] {
|
||||
-> &'tcx [(LocalDefId, Span)] {
|
||||
eval_always
|
||||
desc { "looking up all possibly unused extern crates" }
|
||||
}
|
||||
|
|
|
@ -925,7 +925,7 @@ pub struct GlobalCtxt<'tcx> {
|
|||
pub consts: CommonConsts<'tcx>,
|
||||
|
||||
/// Resolutions of `extern crate` items produced by resolver.
|
||||
extern_crate_map: FxHashMap<DefId, CrateNum>,
|
||||
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
|
||||
|
||||
/// Map indicating what traits are in scope for places where this
|
||||
/// is relevant; generated by resolve.
|
||||
|
@ -944,7 +944,7 @@ pub struct GlobalCtxt<'tcx> {
|
|||
pub queries: query::Queries<'tcx>,
|
||||
|
||||
maybe_unused_trait_imports: FxHashSet<LocalDefId>,
|
||||
maybe_unused_extern_crates: Vec<(DefId, Span)>,
|
||||
maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
|
||||
/// A map of glob use to a set of names it actually imports. Currently only
|
||||
/// used in save-analysis.
|
||||
glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
|
||||
|
|
|
@ -120,10 +120,10 @@ mod sty;
|
|||
pub struct ResolverOutputs {
|
||||
pub definitions: rustc_hir::definitions::Definitions,
|
||||
pub cstore: Box<CrateStoreDyn>,
|
||||
pub extern_crate_map: FxHashMap<DefId, CrateNum>,
|
||||
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
|
||||
pub trait_map: FxHashMap<hir::HirId, Vec<hir::TraitCandidate<hir::HirId>>>,
|
||||
pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
|
||||
pub maybe_unused_extern_crates: Vec<(DefId, Span)>,
|
||||
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
|
||||
pub export_map: ExportMap<hir::HirId>,
|
||||
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
|
||||
/// Extern prelude entries. The value is `true` if the entry was introduced
|
||||
|
|
|
@ -130,7 +130,7 @@ impl<'a> Resolver<'a> {
|
|||
Some(def_id) => def_id,
|
||||
None => return self.ast_transform_scopes.get(&expn_id).unwrap_or(&self.graph_root),
|
||||
};
|
||||
if let Some(id) = self.definitions.as_local_node_id(def_id) {
|
||||
if let Some(id) = def_id.as_local() {
|
||||
self.local_macro_def_scopes[&id]
|
||||
} else {
|
||||
let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap();
|
||||
|
@ -640,9 +640,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
|||
} else if orig_name == Some(kw::SelfLower) {
|
||||
self.r.graph_root
|
||||
} else {
|
||||
let def_id = self.r.definitions.local_def_id(item.id);
|
||||
let crate_id =
|
||||
self.r.crate_loader.process_extern_crate(item, &self.r.definitions);
|
||||
self.r.extern_crate_map.insert(item.id, crate_id);
|
||||
self.r.extern_crate_map.insert(def_id, crate_id);
|
||||
self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
|
||||
};
|
||||
|
||||
|
@ -1173,10 +1174,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
|||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let def_id = self.r.definitions.local_def_id(item.id).to_def_id();
|
||||
let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id);
|
||||
self.r.macro_map.insert(def_id, ext);
|
||||
self.r.local_macro_def_scopes.insert(item.id, parent_scope.module);
|
||||
let def_id = self.r.definitions.local_def_id(item.id);
|
||||
let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id.to_def_id());
|
||||
self.r.macro_map.insert(def_id.to_def_id(), ext);
|
||||
self.r.local_macro_def_scopes.insert(def_id, parent_scope.module);
|
||||
|
||||
if macro_rules {
|
||||
let ident = ident.normalize_to_macros_2_0();
|
||||
|
|
|
@ -64,8 +64,9 @@ impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> {
|
|||
fn check_import(&mut self, id: ast::NodeId) {
|
||||
let mut used = false;
|
||||
self.r.per_ns(|this, ns| used |= this.used_imports.contains(&(id, ns)));
|
||||
let def_id = self.r.definitions.local_def_id(id);
|
||||
if !used {
|
||||
if self.r.maybe_unused_trait_imports.contains(&id) {
|
||||
if self.r.maybe_unused_trait_imports.contains(&def_id) {
|
||||
// Check later.
|
||||
return;
|
||||
}
|
||||
|
@ -73,7 +74,7 @@ impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> {
|
|||
} else {
|
||||
// This trait import is definitely used, in a way other than
|
||||
// method resolution.
|
||||
self.r.maybe_unused_trait_imports.remove(&id);
|
||||
self.r.maybe_unused_trait_imports.remove(&def_id);
|
||||
if let Some(i) = self.unused_imports.get_mut(&self.base_id) {
|
||||
i.unused.remove(&id);
|
||||
}
|
||||
|
@ -245,7 +246,8 @@ impl Resolver<'_> {
|
|||
}
|
||||
}
|
||||
ImportKind::ExternCrate { .. } => {
|
||||
self.maybe_unused_extern_crates.push((import.id, import.span));
|
||||
let def_id = self.definitions.local_def_id(import.id);
|
||||
self.maybe_unused_extern_crates.push((def_id, import.span));
|
||||
}
|
||||
ImportKind::MacroUse => {
|
||||
let msg = "unused `#[macro_use]` import";
|
||||
|
|
|
@ -2209,7 +2209,8 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
) -> SmallVec<[NodeId; 1]> {
|
||||
let mut import_ids = smallvec![];
|
||||
while let NameBindingKind::Import { import, binding, .. } = kind {
|
||||
self.r.maybe_unused_trait_imports.insert(import.id);
|
||||
let id = self.r.definitions.local_def_id(import.id);
|
||||
self.r.maybe_unused_trait_imports.insert(id);
|
||||
self.r.add_to_glob_map(&import, trait_name);
|
||||
import_ids.push(import.id);
|
||||
kind = &binding.kind;
|
||||
|
|
|
@ -37,7 +37,7 @@ use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes};
|
|||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
|
||||
use rustc_hir::definitions::{DefKey, Definitions};
|
||||
use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint};
|
||||
use rustc_hir::{GlobMap, TraitMap};
|
||||
use rustc_hir::TraitMap;
|
||||
use rustc_metadata::creader::{CStore, CrateLoader};
|
||||
use rustc_middle::hir::exports::ExportMap;
|
||||
use rustc_middle::middle::cstore::{CrateStore, MetadataLoaderDyn};
|
||||
|
@ -866,7 +866,7 @@ pub struct Resolver<'a> {
|
|||
label_res_map: NodeMap<NodeId>,
|
||||
|
||||
/// `CrateNum` resolutions of `extern crate` items.
|
||||
extern_crate_map: NodeMap<CrateNum>,
|
||||
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
|
||||
export_map: ExportMap<NodeId>,
|
||||
trait_map: TraitMap<NodeId>,
|
||||
|
||||
|
@ -895,11 +895,11 @@ pub struct Resolver<'a> {
|
|||
underscore_disambiguator: u32,
|
||||
|
||||
/// Maps glob imports to the names of items actually imported.
|
||||
glob_map: GlobMap,
|
||||
glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
|
||||
|
||||
used_imports: FxHashSet<(NodeId, Namespace)>,
|
||||
maybe_unused_trait_imports: NodeSet,
|
||||
maybe_unused_extern_crates: Vec<(NodeId, Span)>,
|
||||
maybe_unused_trait_imports: FxHashSet<LocalDefId>,
|
||||
maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
|
||||
|
||||
/// Privacy errors are delayed until the end in order to deduplicate them.
|
||||
privacy_errors: Vec<PrivacyError<'a>>,
|
||||
|
@ -924,7 +924,7 @@ pub struct Resolver<'a> {
|
|||
dummy_ext_bang: Lrc<SyntaxExtension>,
|
||||
dummy_ext_derive: Lrc<SyntaxExtension>,
|
||||
non_macro_attrs: [Lrc<SyntaxExtension>; 2],
|
||||
local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
|
||||
local_macro_def_scopes: FxHashMap<LocalDefId, Module<'a>>,
|
||||
ast_transform_scopes: FxHashMap<ExpnId, Module<'a>>,
|
||||
unused_macros: NodeMap<Span>,
|
||||
proc_macro_stubs: NodeSet,
|
||||
|
@ -1269,11 +1269,7 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
pub fn into_outputs(self) -> ResolverOutputs {
|
||||
let definitions = self.definitions;
|
||||
let extern_crate_map = self
|
||||
.extern_crate_map
|
||||
.into_iter()
|
||||
.map(|(k, v)| (definitions.local_def_id(k).to_def_id(), v))
|
||||
.collect();
|
||||
let extern_crate_map = self.extern_crate_map;
|
||||
let export_map = self
|
||||
.export_map
|
||||
.into_iter()
|
||||
|
@ -1298,21 +1294,9 @@ impl<'a> Resolver<'a> {
|
|||
)
|
||||
})
|
||||
.collect();
|
||||
let maybe_unused_trait_imports = self
|
||||
.maybe_unused_trait_imports
|
||||
.into_iter()
|
||||
.map(|id| definitions.local_def_id(id))
|
||||
.collect();
|
||||
let maybe_unused_extern_crates = self
|
||||
.maybe_unused_extern_crates
|
||||
.into_iter()
|
||||
.map(|(id, sp)| (definitions.local_def_id(id).to_def_id(), sp))
|
||||
.collect();
|
||||
let glob_map = self
|
||||
.glob_map
|
||||
.into_iter()
|
||||
.map(|(id, names)| (definitions.local_def_id(id), names))
|
||||
.collect();
|
||||
let maybe_unused_trait_imports = self.maybe_unused_trait_imports;
|
||||
let maybe_unused_extern_crates = self.maybe_unused_extern_crates;
|
||||
let glob_map = self.glob_map;
|
||||
ResolverOutputs {
|
||||
definitions: definitions,
|
||||
cstore: Box::new(self.crate_loader.into_cstore()),
|
||||
|
@ -1334,11 +1318,7 @@ impl<'a> Resolver<'a> {
|
|||
ResolverOutputs {
|
||||
definitions: self.definitions.clone(),
|
||||
cstore: Box::new(self.cstore().clone()),
|
||||
extern_crate_map: self
|
||||
.extern_crate_map
|
||||
.iter()
|
||||
.map(|(&k, &v)| (self.definitions.local_def_id(k).to_def_id(), v))
|
||||
.collect(),
|
||||
extern_crate_map: self.extern_crate_map.clone(),
|
||||
export_map: self
|
||||
.export_map
|
||||
.iter()
|
||||
|
@ -1366,21 +1346,9 @@ impl<'a> Resolver<'a> {
|
|||
)
|
||||
})
|
||||
.collect(),
|
||||
glob_map: self
|
||||
.glob_map
|
||||
.iter()
|
||||
.map(|(&id, names)| (self.definitions.local_def_id(id), names.clone()))
|
||||
.collect(),
|
||||
maybe_unused_trait_imports: self
|
||||
.maybe_unused_trait_imports
|
||||
.iter()
|
||||
.map(|&id| self.definitions.local_def_id(id))
|
||||
.collect(),
|
||||
maybe_unused_extern_crates: self
|
||||
.maybe_unused_extern_crates
|
||||
.iter()
|
||||
.map(|&(id, sp)| (self.definitions.local_def_id(id).to_def_id(), sp))
|
||||
.collect(),
|
||||
glob_map: self.glob_map.clone(),
|
||||
maybe_unused_trait_imports: self.maybe_unused_trait_imports.clone(),
|
||||
maybe_unused_extern_crates: self.maybe_unused_extern_crates.clone(),
|
||||
extern_prelude: self
|
||||
.extern_prelude
|
||||
.iter()
|
||||
|
@ -1522,7 +1490,8 @@ impl<'a> Resolver<'a> {
|
|||
#[inline]
|
||||
fn add_to_glob_map(&mut self, import: &Import<'_>, ident: Ident) {
|
||||
if import.is_glob() {
|
||||
self.glob_map.entry(import.id).or_default().insert(ident.name);
|
||||
let def_id = self.definitions.local_def_id(import.id);
|
||||
self.glob_map.entry(def_id).or_default().insert(ident.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@ pub fn target() -> TargetResult {
|
|||
target_endian: "little".to_string(),
|
||||
target_pointer_width: "64".to_string(),
|
||||
target_c_int_width: "32".to_string(),
|
||||
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
.to_string(),
|
||||
arch: "x86_64".to_string(),
|
||||
target_os: "illumos".to_string(),
|
||||
target_env: String::new(),
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#![feature(in_band_lifetimes)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(str_strip)]
|
||||
#![feature(option_zip)]
|
||||
#![recursion_limit = "512"] // For rustdoc
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE};
|
||||
use rustc_hir::def_id::{DefId, DefIdSet, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::lint;
|
||||
|
@ -70,7 +70,7 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
|
|||
// Collect first the crates that are completely unused. These we
|
||||
// can always suggest removing (no matter which edition we are
|
||||
// in).
|
||||
let unused_extern_crates: FxHashMap<DefId, Span> = tcx
|
||||
let unused_extern_crates: FxHashMap<LocalDefId, Span> = tcx
|
||||
.maybe_unused_extern_crates(LOCAL_CRATE)
|
||||
.iter()
|
||||
.filter(|&&(def_id, _)| {
|
||||
|
@ -88,7 +88,7 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
|
|||
// Note that if we carry through to the `extern_mod_stmt_cnum` query
|
||||
// below it'll cause a panic because `def_id` is actually bogus at this
|
||||
// point in time otherwise.
|
||||
if tcx.hir().find(tcx.hir().as_local_hir_id(def_id.expect_local())).is_none() {
|
||||
if tcx.hir().find(tcx.hir().as_local_hir_id(def_id)).is_none() {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
|
@ -112,13 +112,14 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
|
|||
});
|
||||
|
||||
for extern_crate in &crates_to_lint {
|
||||
let id = tcx.hir().as_local_hir_id(extern_crate.def_id.expect_local());
|
||||
let def_id = extern_crate.def_id.expect_local();
|
||||
let id = tcx.hir().as_local_hir_id(def_id);
|
||||
let item = tcx.hir().expect_item(id);
|
||||
|
||||
// If the crate is fully unused, we suggest removing it altogether.
|
||||
// We do this in any edition.
|
||||
if extern_crate.warn_if_unused {
|
||||
if let Some(&span) = unused_extern_crates.get(&extern_crate.def_id) {
|
||||
if let Some(&span) = unused_extern_crates.get(&def_id) {
|
||||
tcx.struct_span_lint_hir(lint, id, span, |lint| {
|
||||
// Removal suggestion span needs to include attributes (Issue #54400)
|
||||
let span_with_attrs = tcx
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::cmp::Ordering;
|
||||
use crate::convert::TryInto;
|
||||
use crate::fmt;
|
||||
use crate::hash;
|
||||
|
@ -36,7 +37,7 @@ use crate::vec;
|
|||
/// assert_eq!(socket.port(), 8080);
|
||||
/// assert_eq!(socket.is_ipv4(), true);
|
||||
/// ```
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub enum SocketAddr {
|
||||
/// An IPv4 socket address.
|
||||
|
@ -653,11 +654,75 @@ impl PartialEq for SocketAddrV6 {
|
|||
&& self.inner.sin6_scope_id == other.inner.sin6_scope_id
|
||||
}
|
||||
}
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl PartialEq<SocketAddrV4> for SocketAddr {
|
||||
fn eq(&self, other: &SocketAddrV4) -> bool {
|
||||
match self {
|
||||
SocketAddr::V4(v4) => v4 == other,
|
||||
SocketAddr::V6(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl PartialEq<SocketAddrV6> for SocketAddr {
|
||||
fn eq(&self, other: &SocketAddrV6) -> bool {
|
||||
match self {
|
||||
SocketAddr::V4(_) => false,
|
||||
SocketAddr::V6(v6) => v6 == other,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl PartialEq<SocketAddr> for SocketAddrV4 {
|
||||
fn eq(&self, other: &SocketAddr) -> bool {
|
||||
match other {
|
||||
SocketAddr::V4(v4) => self == v4,
|
||||
SocketAddr::V6(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl PartialEq<SocketAddr> for SocketAddrV6 {
|
||||
fn eq(&self, other: &SocketAddr) -> bool {
|
||||
match other {
|
||||
SocketAddr::V4(_) => false,
|
||||
SocketAddr::V6(v6) => self == v6,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Eq for SocketAddrV4 {}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Eq for SocketAddrV6 {}
|
||||
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl PartialOrd for SocketAddrV4 {
|
||||
fn partial_cmp(&self, other: &SocketAddrV4) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl PartialOrd for SocketAddrV6 {
|
||||
fn partial_cmp(&self, other: &SocketAddrV6) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl Ord for SocketAddrV4 {
|
||||
fn cmp(&self, other: &SocketAddrV4) -> Ordering {
|
||||
self.ip().cmp(other.ip()).then(self.port().cmp(&other.port()))
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl Ord for SocketAddrV6 {
|
||||
fn cmp(&self, other: &SocketAddrV6) -> Ordering {
|
||||
self.ip().cmp(other.ip()).then(self.port().cmp(&other.port()))
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl hash::Hash for SocketAddrV4 {
|
||||
fn hash<H: hash::Hasher>(&self, s: &mut H) {
|
||||
|
@ -1102,4 +1167,44 @@ mod tests {
|
|||
assert!(!v6.is_ipv4());
|
||||
assert!(v6.is_ipv6());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compare() {
|
||||
let v4_1 = "224.120.45.1:23456".parse::<SocketAddrV4>().unwrap();
|
||||
let v4_2 = "224.210.103.5:12345".parse::<SocketAddrV4>().unwrap();
|
||||
let v4_3 = "224.210.103.5:23456".parse::<SocketAddrV4>().unwrap();
|
||||
let v6_1 = "[2001:db8:f00::1002]:23456".parse::<SocketAddrV6>().unwrap();
|
||||
let v6_2 = "[2001:db8:f00::2001]:12345".parse::<SocketAddrV6>().unwrap();
|
||||
let v6_3 = "[2001:db8:f00::2001]:23456".parse::<SocketAddrV6>().unwrap();
|
||||
|
||||
// equality
|
||||
assert_eq!(v4_1, v4_1);
|
||||
assert_eq!(v6_1, v6_1);
|
||||
assert_eq!(v4_1, SocketAddr::V4(v4_1));
|
||||
assert_eq!(v6_1, SocketAddr::V6(v6_1));
|
||||
assert_eq!(SocketAddr::V4(v4_1), SocketAddr::V4(v4_1));
|
||||
assert_eq!(SocketAddr::V6(v6_1), SocketAddr::V6(v6_1));
|
||||
assert!(v4_1 != SocketAddr::V6(v6_1));
|
||||
assert!(v6_1 != SocketAddr::V4(v4_1));
|
||||
assert!(v4_1 != v4_2);
|
||||
assert!(v6_1 != v6_2);
|
||||
|
||||
// compare different addresses
|
||||
assert!(v4_1 < v4_2);
|
||||
assert!(v6_1 < v6_2);
|
||||
assert!(v4_2 > v4_1);
|
||||
assert!(v6_2 > v6_1);
|
||||
|
||||
// compare the same address with different ports
|
||||
assert!(v4_2 < v4_3);
|
||||
assert!(v6_2 < v6_3);
|
||||
assert!(v4_3 > v4_2);
|
||||
assert!(v6_3 > v6_2);
|
||||
|
||||
// compare different addresses with the same port
|
||||
assert!(v4_1 < v4_3);
|
||||
assert!(v6_1 < v6_3);
|
||||
assert!(v4_3 > v4_1);
|
||||
assert!(v6_3 > v6_1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ fn main() {
|
|||
};
|
||||
|
||||
// Neither of these generators have the resume arg live across the `yield`, so they should be
|
||||
// 4 Bytes in size (only storing the discriminant)
|
||||
// 1 Byte in size (only storing the discriminant)
|
||||
assert_eq!(size_of_val(&gen_copy), 1);
|
||||
assert_eq!(size_of_val(&gen_move), 1);
|
||||
}
|
||||
|
|
|
@ -2,20 +2,27 @@
|
|||
|
||||
#[repr(packed)]
|
||||
pub struct Good {
|
||||
data: &'static u32,
|
||||
data2: [&'static u32; 2],
|
||||
data: u64,
|
||||
ptr: &'static u64,
|
||||
data2: [u64; 2],
|
||||
aligned: [u8; 32],
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let good = Good { data: &0, data2: [&0, &0], aligned: [0; 32] };
|
||||
let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] };
|
||||
|
||||
let _ = &good.ptr; //~ ERROR reference to packed field
|
||||
let _ = &good.data; //~ ERROR reference to packed field
|
||||
// Error even when turned into raw pointer immediately.
|
||||
let _ = &good.data as *const _; //~ ERROR reference to packed field
|
||||
let _: *const _ = &good.data; //~ ERROR reference to packed field
|
||||
// Error on method call.
|
||||
let _ = good.data.clone(); //~ ERROR reference to packed field
|
||||
// Error for nested fields.
|
||||
let _ = &good.data2[0]; //~ ERROR reference to packed field
|
||||
let _ = &*good.data; // ok, behind a pointer
|
||||
|
||||
let _ = &*good.ptr; // ok, behind a pointer
|
||||
let _ = &good.aligned; // ok, has align 1
|
||||
let _ = &good.aligned[2]; // ok, has align 1
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error: reference to packed field is unaligned
|
||||
--> $DIR/unaligned_references.rs:14:17
|
||||
--> $DIR/unaligned_references.rs:15:17
|
||||
|
|
||||
LL | let _ = &good.data;
|
||||
| ^^^^^^^^^^
|
||||
LL | let _ = &good.ptr;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unaligned_references.rs:1:9
|
||||
|
@ -12,7 +12,15 @@ LL | #![deny(unaligned_references)]
|
|||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
|
||||
error: reference to packed field is unaligned
|
||||
--> $DIR/unaligned_references.rs:15:17
|
||||
--> $DIR/unaligned_references.rs:16:17
|
||||
|
|
||||
LL | let _ = &good.data;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
|
||||
error: reference to packed field is unaligned
|
||||
--> $DIR/unaligned_references.rs:18:17
|
||||
|
|
||||
LL | let _ = &good.data as *const _;
|
||||
| ^^^^^^^^^^
|
||||
|
@ -20,7 +28,7 @@ LL | let _ = &good.data as *const _;
|
|||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
|
||||
error: reference to packed field is unaligned
|
||||
--> $DIR/unaligned_references.rs:16:27
|
||||
--> $DIR/unaligned_references.rs:19:27
|
||||
|
|
||||
LL | let _: *const _ = &good.data;
|
||||
| ^^^^^^^^^^
|
||||
|
@ -28,12 +36,20 @@ LL | let _: *const _ = &good.data;
|
|||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
|
||||
error: reference to packed field is unaligned
|
||||
--> $DIR/unaligned_references.rs:17:17
|
||||
--> $DIR/unaligned_references.rs:21:17
|
||||
|
|
||||
LL | let _ = good.data.clone();
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
|
||||
error: reference to packed field is unaligned
|
||||
--> $DIR/unaligned_references.rs:23:17
|
||||
|
|
||||
LL | let _ = &good.data2[0];
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
|
11
src/test/ui/mir/issue-66930.rs
Normal file
11
src/test/ui/mir/issue-66930.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// check-pass
|
||||
// compile-flags: --emit=mir,link
|
||||
// Regression test for #66930, this ICE requires `--emit=mir` flag.
|
||||
|
||||
static UTF8_CHAR_WIDTH: [u8; 0] = [];
|
||||
|
||||
pub fn utf8_char_width(b: u8) -> usize {
|
||||
UTF8_CHAR_WIDTH[b as usize] as usize
|
||||
}
|
||||
|
||||
fn main() {}
|
9
src/test/ui/unused-crate-deps/lint-group.rs
Normal file
9
src/test/ui/unused-crate-deps/lint-group.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
// `unused_crate_dependencies` is not currently in the `unused` group
|
||||
// due to false positives from Cargo.
|
||||
|
||||
// check-pass
|
||||
// aux-crate:bar=bar.rs
|
||||
|
||||
#![deny(unused)]
|
||||
|
||||
fn main() {}
|
|
@ -1,6 +1,5 @@
|
|||
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(str_strip)]
|
||||
|
||||
// FIXME: switch to something more ergonomic here, once available.
|
||||
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue