[[package]]
name = "ena"
-version = "0.9.2"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
version = "0.0.0"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum elasticlunr-rs 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4511b63d69dd5d31e8e29aed2c132c413f87acea8035d0584801feaab9dd1f0f"
-"checksum ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b449f3b18c89d2dbe40548d2ee4fa58ea0a08b761992da6ecb9788e4688834"
+"checksum ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc8393b3c7352f94092497f6b52019643e493b6b890eb417cdb7c46117e621"
"checksum endian-type 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
"checksum env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "be27f8ea102a7182093a80d98f0b78623b580eda8791cbe8e2345fe6e57567a6"
if let Ok(host_linker) = env::var("RUSTC_HOST_LINKER") {
cmd.arg(format!("-Clinker={}", host_linker));
}
-
- if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") {
- if s == "true" {
- cmd.arg("-C").arg("target-feature=+crt-static");
- }
- if s == "false" {
- cmd.arg("-C").arg("target-feature=-crt-static");
- }
- }
}
if env::var_os("RUSTC_PARALLEL_QUERIES").is_some() {
"""
return os.path.join(self.build_dir, self.build, "stage0")
- def get_toml(self, key, section=None):
+ def get_toml(self, key):
"""Returns the value of the given key in config.toml, otherwise returns None
>>> rb = RustBuild()
>>> rb.get_toml("key3") is None
True
-
- Optionally also matches the section the key appears in
-
- >>> rb.config_toml = '[a]\\nkey = "value1"\\n[b]\\nkey = "value2"'
- >>> rb.get_toml('key', 'a')
- 'value1'
- >>> rb.get_toml('key', 'b')
- 'value2'
- >>> rb.get_toml('key', 'c') is None
- True
"""
-
- cur_section = None
for line in self.config_toml.splitlines():
- section_match = re.match(r'^\s*\[(.*)\]\s*$', line)
- if section_match is not None:
- cur_section = section_match.group(1)
-
match = re.match(r'^{}\s*=(.*)$'.format(key), line)
if match is not None:
value = match.group(1)
- if section is None or section == cur_section:
- return self.get_string(value) or value.strip()
+ return self.get_string(value) or value.strip()
return None
def cargo(self):
env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
(os.pathsep + env["LIBRARY_PATH"]) \
if "LIBRARY_PATH" in env else ""
- env["RUSTFLAGS"] = "-Cdebuginfo=2 "
-
- build_section = "target.{}".format(self.build_triple())
- target_features = []
- if self.get_toml("crt-static", build_section) == "true":
- target_features += ["+crt-static"]
- elif self.get_toml("crt-static", build_section) == "false":
- target_features += ["-crt-static"]
- if target_features:
- env["RUSTFLAGS"] += "-C target-feature=" + (",".join(target_features)) + " "
-
+ env["RUSTFLAGS"] = "-Cdebuginfo=2"
env["PATH"] = os.path.join(self.bin_root(), "bin") + \
os.pathsep + env["PATH"]
if not os.path.isfile(self.cargo()):
cargo.env("RUSTC_CRT_STATIC", x.to_string());
}
- if let Some(x) = self.crt_static(compiler.host) {
- cargo.env("RUSTC_HOST_CRT_STATIC", x.to_string());
- }
-
// Enable usage of unstable features
cargo.env("RUSTC_BOOTSTRAP", "1");
self.add_rust_test_threads(&mut cargo);
The warning can be fixed by renaming the parent module to "mod.rs" and moving
it into its own directory if appropriate.
-## legacy-imports
-
-This lint detects names that resolve to ambiguous glob imports. Some example
-code that triggers this lint:
-
-```rust,ignore
-pub struct Foo;
-
-mod bar {
- struct Foo;
-
- mod baz {
- use *;
- use bar::*;
- fn f(_: Foo) {}
- }
-}
-```
-
-This will produce:
-
-```text
-error: `Foo` is ambiguous
- --> src/main.rs:9:17
- |
-7 | use *;
- | - `Foo` could refer to the name imported here
-8 | use bar::*;
- | ------ `Foo` could also refer to the name imported here
-9 | fn f(_: Foo) {}
- | ^^^
- |
- = note: #[deny(legacy_imports)] on by default
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #38260 <https://github.com/rust-lang/rust/issues/38260>
-```
-
## missing-fragment-specifier
# fn foo() {}
```
-`compile_fail` tells `rustdoc` that the compilation should fail. If it
-compiles, then the test will fail. However please note that code failing
-with the current Rust release may work in a future release, as new features
-are added.
+The `no_run` attribute will compile your code, but not run it. This is
+important for examples such as "Here's how to retrieve a web page,"
+which you would want to ensure compiles, but might be run in a test
+environment that has no network access.
```text
/// ```compile_fail
/// ```
```
-The `no_run` attribute will compile your code, but not run it. This is
-important for examples such as "Here's how to retrieve a web page,"
-which you would want to ensure compiles, but might be run in a test
-environment that has no network access.
+`compile_fail` tells `rustdoc` that the compilation should fail. If it
+compiles, then the test will fail. However please note that code failing
+with the current Rust release may work in a future release, as new features
+are added.
ty::ReLateBound(..) |
ty::ReVar(..) |
ty::ReSkolemized(..) => {
- bug!("TypeIdHasher: unexpected region {:?}", *self)
+ bug!("StableHasher: unexpected region {:?}", *self)
}
}
}
// should think carefully about whether it needs to be cleared
// or updated in some way.
let RegionConstraintCollector {
- var_infos,
+ var_infos: _,
data,
lubs,
glbs,
// un-unified" state. Note that when we unify `a` and `b`, we
// also insert `a <= b` and a `b <= a` edges, so the
// `RegionConstraintData` contains the relationship here.
- *unification_table = ut::UnificationTable::new();
- for vid in var_infos.indices() {
- unification_table.new_key(unify_key::RegionVidKey { min_vid: vid });
- }
+ unification_table.reset_unifications(|vid| unify_key::RegionVidKey { min_vid: vid });
mem::replace(data, RegionConstraintData::default())
}
not named `mod.rs`"
}
-declare_lint! {
- pub LEGACY_IMPORTS,
- Deny,
- "detects names that resolve to ambiguous glob imports with RFC 1560"
-}
-
declare_lint! {
pub LEGACY_CONSTRUCTOR_VISIBILITY,
Deny,
SAFE_PACKED_BORROWS,
PATTERNS_IN_FNS_WITHOUT_BODY,
LEGACY_DIRECTORY_OWNERSHIP,
- LEGACY_IMPORTS,
LEGACY_CONSTRUCTOR_VISIBILITY,
MISSING_FRAGMENT_SPECIFIER,
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
use std::io;
use std::rc::Rc;
use syntax::ast::{self, NodeId};
+use syntax::ptr::P;
use syntax::symbol::keywords;
use syntax_pos::Span;
lsets.warn_about_unused_args(body, entry_ln);
}
-fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
- local.pat.each_binding(|_, p_id, sp, path1| {
- debug!("adding local variable {}", p_id);
+fn add_from_pat<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, pat: &P<hir::Pat>) {
+ // For struct patterns, take note of which fields used shorthand
+ // (`x` rather than `x: x`).
+ //
+ // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
+ // phased out in favor of `HirId`s; however, we need to match the signature of
+ // `each_binding`, which uses `NodeIds`.
+ let mut shorthand_field_ids = NodeSet();
+ let mut pats = VecDeque::new();
+ pats.push_back(pat);
+ while let Some(pat) = pats.pop_front() {
+ use hir::PatKind::*;
+ match pat.node {
+ Binding(_, _, _, ref inner_pat) => {
+ pats.extend(inner_pat.iter());
+ }
+ Struct(_, ref fields, _) => {
+ for field in fields {
+ if field.node.is_shorthand {
+ shorthand_field_ids.insert(field.node.pat.id);
+ }
+ }
+ }
+ Ref(ref inner_pat, _) |
+ Box(ref inner_pat) => {
+ pats.push_back(inner_pat);
+ }
+ TupleStruct(_, ref inner_pats, _) |
+ Tuple(ref inner_pats, _) => {
+ pats.extend(inner_pats.iter());
+ }
+ Slice(ref pre_pats, ref inner_pat, ref post_pats) => {
+ pats.extend(pre_pats.iter());
+ pats.extend(inner_pat.iter());
+ pats.extend(post_pats.iter());
+ }
+ _ => {}
+ }
+ }
+
+ pat.each_binding(|_bm, p_id, _sp, path1| {
let name = path1.node;
- ir.add_live_node_for_node(p_id, VarDefNode(sp));
+ ir.add_live_node_for_node(p_id, VarDefNode(path1.span));
ir.add_variable(Local(LocalInfo {
id: p_id,
name,
- is_shorthand: false,
+ is_shorthand: shorthand_field_ids.contains(&p_id)
}));
});
+}
+
+fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
+ add_from_pat(ir, &local.pat);
intravisit::walk_local(ir, local);
}
fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
- for mut pat in &arm.pats {
- // For struct patterns, take note of which fields used shorthand
- // (`x` rather than `x: x`).
- //
- // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
- // phased out in favor of `HirId`s; however, we need to match the signature of
- // `each_binding`, which uses `NodeIds`.
- let mut shorthand_field_ids = NodeSet();
- let mut pats = VecDeque::new();
- pats.push_back(pat);
- while let Some(pat) = pats.pop_front() {
- use hir::PatKind::*;
- match pat.node {
- Binding(_, _, _, ref inner_pat) => {
- pats.extend(inner_pat.iter());
- }
- Struct(_, ref fields, _) => {
- for field in fields {
- if field.node.is_shorthand {
- shorthand_field_ids.insert(field.node.pat.id);
- }
- }
- }
- Ref(ref inner_pat, _) |
- Box(ref inner_pat) => {
- pats.push_back(inner_pat);
- }
- TupleStruct(_, ref inner_pats, _) |
- Tuple(ref inner_pats, _) => {
- pats.extend(inner_pats.iter());
- }
- Slice(ref pre_pats, ref inner_pat, ref post_pats) => {
- pats.extend(pre_pats.iter());
- pats.extend(inner_pat.iter());
- pats.extend(post_pats.iter());
- }
- _ => {}
- }
- }
-
- pat.each_binding(|bm, p_id, _sp, path1| {
- debug!("adding local variable {} from match with bm {:?}",
- p_id, bm);
- let name = path1.node;
- ir.add_live_node_for_node(p_id, VarDefNode(path1.span));
- ir.add_variable(Local(LocalInfo {
- id: p_id,
- name: name,
- is_shorthand: shorthand_field_ids.contains(&p_id)
- }));
- })
+ for pat in &arm.pats {
+ add_from_pat(ir, pat);
}
intravisit::walk_arm(ir, arm);
}
"print the result of the monomorphization collection pass"),
mir_opt_level: usize = (1, parse_uint, [TRACKED],
"set the MIR optimization level (0-3, default: 1)"),
- mutable_noalias: bool = (false, parse_bool, [TRACKED],
- "emit noalias metadata for mutable references"),
+ mutable_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
+ "emit noalias metadata for mutable references (default: yes on LLVM >= 6)"),
arg_align_attributes: bool = (false, parse_bool, [TRACKED],
"emit align metadata for reference arguments"),
dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED],
use hir::map::{DefPathData, Node};
use hir;
use ich::NodeIdHashingMode;
-use middle::const_val::ConstVal;
use traits::{self, ObligationCause};
use ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
-use ty::fold::TypeVisitor;
use ty::subst::{Substs, UnpackedKind};
use ty::maps::TyCtxtAt;
use ty::TypeVariants::*;
use util::common::ErrorReported;
use middle::lang_items;
-use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
- HashStable};
+use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use rustc_data_structures::fx::FxHashMap;
use std::{cmp, fmt};
-use std::hash::Hash;
-use std::intrinsics;
use syntax::ast;
use syntax::attr::{self, SignedInt, UnsignedInt};
use syntax_pos::{Span, DUMMY_SP};
}
}
-pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, W> {
- tcx: TyCtxt<'a, 'gcx, 'tcx>,
- state: StableHasher<W>,
-}
-
-impl<'a, 'gcx, 'tcx, W> TypeIdHasher<'a, 'gcx, 'tcx, W>
- where W: StableHasherResult
-{
- pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self {
- TypeIdHasher { tcx: tcx, state: StableHasher::new() }
- }
-
- pub fn finish(self) -> W {
- self.state.finish()
- }
-
- pub fn hash<T: Hash>(&mut self, x: T) {
- x.hash(&mut self.state);
- }
-
- fn hash_discriminant_u8<T>(&mut self, x: &T) {
- let v = unsafe {
- intrinsics::discriminant_value(x)
- };
- let b = v as u8;
- assert_eq!(v, b as u64);
- self.hash(b)
- }
-
- fn def_id(&mut self, did: DefId) {
- // Hash the DefPath corresponding to the DefId, which is independent
- // of compiler internal state. We already have a stable hash value of
- // all DefPaths available via tcx.def_path_hash(), so we just feed that
- // into the hasher.
- let hash = self.tcx.def_path_hash(did);
- self.hash(hash);
- }
-}
-
-impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
- where W: StableHasherResult
-{
- fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
- // Distinguish between the Ty variants uniformly.
- self.hash_discriminant_u8(&ty.sty);
-
- match ty.sty {
- TyInt(i) => self.hash(i),
- TyUint(u) => self.hash(u),
- TyFloat(f) => self.hash(f),
- TyArray(_, n) => {
- self.hash_discriminant_u8(&n.val);
- match n.val {
- ConstVal::Value(alloc) => self.hash(alloc),
- ConstVal::Unevaluated(def_id, _) => self.def_id(def_id),
- }
- }
- TyRawPtr(m) => self.hash(m.mutbl),
- TyRef(_, _, mutbl) => self.hash(mutbl),
- TyClosure(def_id, _) |
- TyGenerator(def_id, _, _) |
- TyAnon(def_id, _) |
- TyFnDef(def_id, _) => self.def_id(def_id),
- TyAdt(d, _) => self.def_id(d.did),
- TyForeign(def_id) => self.def_id(def_id),
- TyFnPtr(f) => {
- self.hash(f.unsafety());
- self.hash(f.abi());
- self.hash(f.variadic());
- self.hash(f.inputs().skip_binder().len());
- }
- TyDynamic(ref data, ..) => {
- if let Some(p) = data.principal() {
- self.def_id(p.def_id());
- }
- for d in data.auto_traits() {
- self.def_id(d);
- }
- }
- TyGeneratorWitness(tys) => {
- self.hash(tys.skip_binder().len());
- }
- TyTuple(tys) => {
- self.hash(tys.len());
- }
- TyParam(p) => {
- self.hash(p.idx);
- self.hash(p.name);
- }
- TyProjection(ref data) => {
- self.def_id(data.item_def_id);
- }
- TyNever |
- TyBool |
- TyChar |
- TyStr |
- TySlice(_) => {}
-
- TyError |
- TyInfer(_) => bug!("TypeIdHasher: unexpected type {}", ty)
- }
-
- ty.super_visit_with(self)
- }
-
- fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
- self.hash_discriminant_u8(r);
- match *r {
- ty::ReErased |
- ty::ReStatic |
- ty::ReEmpty => {
- // No variant fields to hash for these ...
- }
- ty::ReCanonical(c) => {
- self.hash(c);
- }
- ty::ReLateBound(db, ty::BrAnon(i)) => {
- self.hash(db.depth);
- self.hash(i);
- }
- ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, .. }) => {
- self.def_id(def_id);
- }
-
- ty::ReClosureBound(..) |
- ty::ReLateBound(..) |
- ty::ReFree(..) |
- ty::ReScope(..) |
- ty::ReVar(..) |
- ty::ReSkolemized(..) => {
- bug!("TypeIdHasher: unexpected region {:?}", r)
- }
- }
- false
- }
-
- fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, x: &ty::Binder<T>) -> bool {
- // Anonymize late-bound regions so that, for example:
- // `for<'a, b> fn(&'a &'b T)` and `for<'a, b> fn(&'b &'a T)`
- // result in the same TypeId (the two types are equivalent).
- self.tcx.anonymize_late_bound_regions(x).super_visit_with(self)
- }
-}
-
impl<'a, 'tcx> ty::TyS<'tcx> {
pub fn moves_by_default(&'tcx self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) {
cmd.args(args);
}
- if let Some(args) = sess.target.target.options.pre_link_args_crt.get(&flavor) {
- if sess.crt_static() {
- cmd.args(args);
- }
- }
if let Some(ref args) = sess.opts.debugging_opts.pre_link_args {
cmd.args(args);
}
cmd.arg(root.join(obj));
}
- if crate_type == config::CrateTypeExecutable && sess.crt_static() {
- for obj in &sess.target.target.options.pre_link_objects_exe_crt {
- cmd.arg(root.join(obj));
- }
-
- for obj in &sess.target.target.options.pre_link_objects_exe_crt_sys {
- if flavor == LinkerFlavor::Gcc {
- cmd.arg(format!("-l:{}", obj));
- }
- }
- }
-
if sess.target.target.options.is_like_emscripten {
cmd.arg("-s");
cmd.arg(if sess.panic_strategy() == PanicStrategy::Abort {
for obj in &sess.target.target.options.post_link_objects {
cmd.arg(root.join(obj));
}
- if sess.crt_static() {
- for obj in &sess.target.target.options.post_link_objects_crt_sys {
- if flavor == LinkerFlavor::Gcc {
- cmd.arg(format!("-l:{}", obj));
- }
- }
- for obj in &sess.target.target.options.post_link_objects_crt {
- cmd.arg(root.join(obj));
- }
- }
if let Some(args) = sess.target.target.options.post_link_args.get(&flavor) {
cmd.args(args);
}
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
DICompositeType, DILexicalBlock, DIFlags};
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc::hir::CodegenFnAttrFlags;
use rustc::hir::def::CtorKind;
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
-use rustc::ty::fold::TypeVisitor;
-use rustc::ty::util::TypeIdHasher;
-use rustc::ich::Fingerprint;
+use rustc::ich::{Fingerprint, NodeIdHashingMode};
use rustc::ty::Instance;
use common::CodegenCx;
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
// The hasher we are using to generate the UniqueTypeId. We want
// something that provides more than the 64 bits of the DefaultHasher.
- let mut type_id_hasher = TypeIdHasher::<Fingerprint>::new(cx.tcx);
- type_id_hasher.visit_ty(type_);
- let unique_type_id = type_id_hasher.finish().to_hex();
+ let mut hasher = StableHasher::<Fingerprint>::new();
+ let mut hcx = cx.tcx.create_stable_hashing_context();
+ let type_ = cx.tcx.erase_regions(&type_);
+ hcx.while_hashing_spans(false, |hcx| {
+ hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+ type_.hash_stable(hcx, &mut hasher);
+ });
+ });
+ let unique_type_id = hasher.finish().to_hex();
let key = self.unique_id_interner.intern(&unique_type_id);
self.type_to_unique_id.insert(type_, UniqueTypeId(key));
use abi::{FnType, FnTypeExt};
use common::*;
+use llvm;
use rustc::hir;
use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
PointerKind::Shared
},
hir::MutMutable => {
- if cx.tcx.sess.opts.debugging_opts.mutable_noalias ||
- cx.tcx.sess.panic_strategy() == PanicStrategy::Abort {
+ // Only emit noalias annotations for LLVM >= 6 or in panic=abort
+ // mode, as prior versions had many bugs in conjunction with
+ // unwinding. See also issue #31681.
+ let mutable_noalias = cx.tcx.sess.opts.debugging_opts.mutable_noalias
+ .unwrap_or(unsafe { llvm::LLVMRustVersionMajor() >= 6 }
+ || cx.tcx.sess.panic_strategy() == PanicStrategy::Abort);
+ if mutable_noalias {
PointerKind::UniqueBorrowed
} else {
PointerKind::Shared
//! virtually impossible. Thus, symbol hash generation exclusively relies on
//! DefPaths which are much more robust in the face of changes to the code base.
-use rustc::middle::weak_lang_items;
-use rustc_mir::monomorphize::Instance;
-use rustc_mir::monomorphize::item::{MonoItem, MonoItemExt, InstantiationMode};
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::hir::map as hir_map;
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc::ty::fold::TypeVisitor;
+use rustc::hir::map::definitions::DefPathData;
+use rustc::ich::NodeIdHashingMode;
+use rustc::middle::weak_lang_items;
use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
use rustc::ty::maps::Providers;
use rustc::ty::subst::Substs;
-use rustc::hir::map::definitions::DefPathData;
+use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::util::common::record_time;
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_mir::monomorphize::item::{InstantiationMode, MonoItem, MonoItemExt};
+use rustc_mir::monomorphize::Instance;
use syntax::attr;
use syntax_pos::symbol::Symbol;
};
}
-fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+fn get_symbol_hash<'a, 'tcx>(
+ tcx: TyCtxt<'a, 'tcx, 'tcx>,
- // the DefId of the item this name is for
- def_id: DefId,
+ // the DefId of the item this name is for
+ def_id: DefId,
- // instance this name will be for
- instance: Instance<'tcx>,
+ // instance this name will be for
+ instance: Instance<'tcx>,
- // type of the item, without any generic
- // parameters substituted; this is
- // included in the hash as a kind of
- // safeguard.
- item_type: Ty<'tcx>,
+ // type of the item, without any generic
+ // parameters substituted; this is
+ // included in the hash as a kind of
+ // safeguard.
+ item_type: Ty<'tcx>,
- // values for generic type parameters,
- // if any.
- substs: &'tcx Substs<'tcx>)
- -> u64 {
- debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs);
+ // values for generic type parameters,
+ // if any.
+ substs: &'tcx Substs<'tcx>,
+) -> u64 {
+ debug!(
+ "get_symbol_hash(def_id={:?}, parameters={:?})",
+ def_id, substs
+ );
- let mut hasher = ty::util::TypeIdHasher::<u64>::new(tcx);
+ let mut hasher = StableHasher::<u64>::new();
+ let mut hcx = tcx.create_stable_hashing_context();
record_time(&tcx.sess.perf_stats.symbol_hash_time, || {
// the main symbol name is not necessarily unique; hash in the
// compiler's internal def-path, guaranteeing each symbol has a
// truly unique path
- hasher.hash(tcx.def_path_hash(def_id));
+ tcx.def_path_hash(def_id).hash_stable(&mut hcx, &mut hasher);
// Include the main item-type. Note that, in this case, the
// assertions about `needs_subst` may not hold, but this item-type
// ought to be the same for every reference anyway.
assert!(!item_type.has_erasable_regions());
- hasher.visit_ty(item_type);
+ hcx.while_hashing_spans(false, |hcx| {
+ hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+ item_type.hash_stable(hcx, &mut hasher);
+ });
+ });
// If this is a function, we hash the signature as well.
// This is not *strictly* needed, but it may help in some
// situations, see the `run-make/a-b-a-linker-guard` test.
if let ty::TyFnDef(..) = item_type.sty {
- item_type.fn_sig(tcx).visit_with(&mut hasher);
+ item_type.fn_sig(tcx).hash_stable(&mut hcx, &mut hasher);
}
// also include any type parameters (for generic items)
assert!(!substs.has_erasable_regions());
assert!(!substs.needs_subst());
- substs.visit_with(&mut hasher);
+ substs.hash_stable(&mut hcx, &mut hasher);
let is_generic = substs.types().next().is_some();
let avoid_cross_crate_conflicts =
if !def_id.is_local() && tcx.share_generics() {
// If we are re-using a monomorphization from another crate,
// we have to compute the symbol hash accordingly.
- let upstream_monomorphizations =
- tcx.upstream_monomorphizations_for(def_id);
+ let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id);
- upstream_monomorphizations.and_then(|monos| monos.get(&substs)
- .cloned())
- .unwrap_or(LOCAL_CRATE)
+ upstream_monomorphizations
+ .and_then(|monos| monos.get(&substs).cloned())
+ .unwrap_or(LOCAL_CRATE)
} else {
LOCAL_CRATE
}
LOCAL_CRATE
};
- hasher.hash(&tcx.original_crate_name(instantiating_crate).as_str()[..]);
- hasher.hash(&tcx.crate_disambiguator(instantiating_crate));
+ (&tcx.original_crate_name(instantiating_crate).as_str()[..])
+ .hash_stable(&mut hcx, &mut hasher);
+ (&tcx.crate_disambiguator(instantiating_crate)).hash_stable(&mut hcx, &mut hasher);
}
});
hasher.finish()
}
-fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
- -> ty::SymbolName
-{
+fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName {
let mut buffer = SymbolPathBuffer::new();
item_path::with_forced_absolute_paths(|| {
tcx.push_item_path(&mut buffer, def_id);
buffer.into_interned()
}
-fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>)
- -> ty::SymbolName
-{
- ty::SymbolName { name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_interned_str() }
+fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName {
+ ty::SymbolName {
+ name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_interned_str(),
+ }
}
-fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>)
- -> String
-{
+fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> String {
let def_id = instance.def_id();
let substs = instance.substs;
- debug!("symbol_name(def_id={:?}, substs={:?})",
- def_id, substs);
+ debug!("symbol_name(def_id={:?}, substs={:?})", def_id, substs);
let node_id = tcx.hir.as_local_node_id(def_id);
let is_foreign = if let Some(id) = node_id {
match tcx.hir.get(id) {
hir_map::NodeForeignItem(_) => true,
- _ => false
+ _ => false,
}
} else {
tcx.is_foreign_item(def_id)
loop {
let key = tcx.def_key(ty_def_id);
match key.disambiguated_data.data {
- DefPathData::TypeNs(_) |
- DefPathData::ValueNs(_) => {
+ DefPathData::TypeNs(_) | DefPathData::ValueNs(_) => {
instance_ty = tcx.type_of(ty_def_id);
break;
}
// to be a value or type-def or something in there
// *somewhere*
ty_def_id.index = key.parent.unwrap_or_else(|| {
- bug!("finding type for {:?}, encountered def-id {:?} with no \
- parent", def_id, ty_def_id);
+ bug!(
+ "finding type for {:?}, encountered def-id {:?} with no \
+ parent",
+ def_id,
+ ty_def_id
+ );
});
}
}
// use C++ name-mangling.
struct SymbolPathBuffer {
result: String,
- temp_buf: String
+ temp_buf: String,
}
impl SymbolPathBuffer {
fn new() -> Self {
let mut result = SymbolPathBuffer {
result: String::with_capacity(64),
- temp_buf: String::with_capacity(16)
+ temp_buf: String::with_capacity(16),
};
result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested
result
fn from_interned(symbol: ty::SymbolName) -> Self {
let mut result = SymbolPathBuffer {
result: String::with_capacity(64),
- temp_buf: String::with_capacity(16)
+ temp_buf: String::with_capacity(16),
};
result.result.push_str(&symbol.name.as_str());
result
}
fn into_interned(self) -> ty::SymbolName {
- ty::SymbolName { name: Symbol::intern(&self.result).as_interned_str() }
+ ty::SymbolName {
+ name: Symbol::intern(&self.result).as_interned_str(),
+ }
}
fn finish(mut self, hash: u64) -> String {
fn push(&mut self, text: &str) {
self.temp_buf.clear();
let need_underscore = sanitize(&mut self.temp_buf, text);
- let _ = write!(self.result, "{}", self.temp_buf.len() + (need_underscore as usize));
+ let _ = write!(
+ self.result,
+ "{}",
+ self.temp_buf.len() + (need_underscore as usize)
+ );
if need_underscore {
self.result.push('_');
}
'-' | ':' => result.push('.'),
// These are legal symbols
- 'a' ... 'z'
- | 'A' ... 'Z'
- | '0' ... '9'
- | '_' | '.' | '$' => result.push(c),
+ 'a'...'z' | 'A'...'Z' | '0'...'9' | '_' | '.' | '$' => result.push(c),
_ => {
result.push('$');
for c in c.escape_unicode().skip(1) {
match c {
- '{' => {},
+ '{' => {}
'}' => result.push('$'),
c => result.push(c),
}
}
// Underscore-qualify anything that didn't start as an ident.
- !result.is_empty() &&
- result.as_bytes()[0] != '_' as u8 &&
- ! (result.as_bytes()[0] as char).is_xid_start()
+ !result.is_empty() && result.as_bytes()[0] != '_' as u8
+ && !(result.as_bytes()[0] as char).is_xid_start()
}
crate-type = ["dylib"]
[dependencies]
-ena = "0.9.1"
+ena = "0.9.3"
log = "0.4"
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
serialize = { path = "../libserialize" }
reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
edition: None,
},
- FutureIncompatibleInfo {
- id: LintId::of(LEGACY_IMPORTS),
- reference: "issue #38260 <https://github.com/rust-lang/rust/issues/38260>",
- edition: None,
- },
FutureIncompatibleInfo {
id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY),
reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
"converted into hard error, see https://github.com/rust-lang/rust/issues/36892");
store.register_removed("extra_requirement_in_impl",
"converted into hard error, see https://github.com/rust-lang/rust/issues/37166");
+ store.register_removed("legacy_imports",
+ "converted into hard error, see https://github.com/rust-lang/rust/issues/38260");
store.register_removed("coerce_never",
"converted into hard error, see https://github.com/rust-lang/rust/issues/48950");
store.register_removed("resolve_trait_on_defaulted_unit",
use rustc::mir::*;
use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor};
use rustc::mir::traversal::ReversePostorder;
-use rustc::ty::TyCtxt;
+use rustc::ty::{self, TyCtxt};
use syntax_pos::Span;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
-use std::iter;
-use std::mem;
-use std::usize;
+use std::{cmp, iter, mem, usize};
/// State of a temporary during collection and promotion.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
}
struct Promoter<'a, 'tcx: 'a> {
+ tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: &'a mut Mir<'tcx>,
promoted: Mir<'tcx>,
temps: &'a mut IndexVec<Local, TempState>,
+ extra_statements: &'a mut Vec<(Location, Statement<'tcx>)>,
/// If true, all nested temps are also kept in the
/// source MIR, not moved to the promoted MIR.
}
fn promote_candidate(mut self, candidate: Candidate) {
- let span = self.promoted.span;
- let new_operand = Operand::Constant(box Constant {
- span,
- ty: self.promoted.return_ty(),
- literal: Literal::Promoted {
+ let mut rvalue = {
+ let promoted = &mut self.promoted;
+ let literal = Literal::Promoted {
index: Promoted::new(self.source.promoted.len())
- }
- });
- let mut rvalue = match candidate {
- Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
- let ref mut statement = self.source[bb].statements[stmt_idx];
- match statement.kind {
- StatementKind::Assign(_, ref mut rvalue) => {
- mem::replace(rvalue, Rvalue::Use(new_operand))
+ };
+ let operand = |ty, span| {
+ promoted.span = span;
+ promoted.local_decls[RETURN_PLACE] =
+ LocalDecl::new_return_place(ty, span);
+ Operand::Constant(box Constant {
+ span,
+ ty,
+ literal
+ })
+ };
+ let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
+ match candidate {
+ Candidate::Ref(loc) => {
+ let ref mut statement = blocks[loc.block].statements[loc.statement_index];
+ match statement.kind {
+ StatementKind::Assign(_, Rvalue::Ref(r, bk, ref mut place)) => {
+ // Find the underlying local for this (necessarilly interior) borrow.
+ // HACK(eddyb) using a recursive function because of mutable borrows.
+ fn interior_base<'a, 'tcx>(place: &'a mut Place<'tcx>)
+ -> &'a mut Place<'tcx> {
+ if let Place::Projection(ref mut proj) = *place {
+ assert_ne!(proj.elem, ProjectionElem::Deref);
+ return interior_base(&mut proj.base);
+ }
+ place
+ }
+ let place = interior_base(place);
+
+ let ty = place.ty(local_decls, self.tcx).to_ty(self.tcx);
+ let ref_ty = self.tcx.mk_ref(r,
+ ty::TypeAndMut {
+ ty,
+ mutbl: bk.to_mutbl_lossy()
+ }
+ );
+ let span = statement.source_info.span;
+
+ // Create a temp to hold the promoted reference.
+ // This is because `*r` requires `r` to be a local,
+ // otherwise we would use the `promoted` directly.
+ let mut promoted_ref = LocalDecl::new_temp(ref_ty, span);
+ promoted_ref.source_info = statement.source_info;
+ let promoted_ref = local_decls.push(promoted_ref);
+ assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref);
+ self.extra_statements.push((loc, Statement {
+ source_info: statement.source_info,
+ kind: StatementKind::Assign(
+ Place::Local(promoted_ref),
+ Rvalue::Use(operand(ref_ty, span)),
+ )
+ }));
+ let promoted_place = Place::Local(promoted_ref).deref();
+
+ Rvalue::Ref(r, bk, mem::replace(place, promoted_place))
+ }
+ _ => bug!()
}
- _ => bug!()
}
- }
- Candidate::Argument { bb, index } => {
- match self.source[bb].terminator_mut().kind {
- TerminatorKind::Call { ref mut args, .. } => {
- Rvalue::Use(mem::replace(&mut args[index], new_operand))
+ Candidate::Argument { bb, index } => {
+ let terminator = blocks[bb].terminator_mut();
+ match terminator.kind {
+ TerminatorKind::Call { ref mut args, .. } => {
+ let ty = args[index].ty(local_decls, self.tcx);
+ let span = terminator.source_info.span;
+ Rvalue::Use(mem::replace(&mut args[index], operand(ty, span)))
+ }
+ _ => bug!()
}
- _ => bug!()
}
}
};
+
+ assert_eq!(self.new_block(), START_BLOCK);
self.visit_rvalue(&mut rvalue, Location {
block: BasicBlock::new(0),
statement_index: usize::MAX
});
+ let span = self.promoted.span;
self.assign(RETURN_PLACE, rvalue, span);
self.source.promoted.push(self.promoted);
}
candidates: Vec<Candidate>) {
// Visit candidates in reverse, in case they're nested.
debug!("promote_candidates({:?})", candidates);
+
+ let mut extra_statements = vec![];
for candidate in candidates.into_iter().rev() {
- let (span, ty) = match candidate {
- Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
- let statement = &mir[bb].statements[stmt_idx];
- let dest = match statement.kind {
- StatementKind::Assign(ref dest, _) => dest,
- _ => {
- span_bug!(statement.source_info.span,
- "expected assignment to promote");
- }
- };
- if let Place::Local(index) = *dest {
- if temps[index] == TempState::PromotedOut {
- // Already promoted.
- continue;
+ match candidate {
+ Candidate::Ref(Location { block, statement_index }) => {
+ match mir[block].statements[statement_index].kind {
+ StatementKind::Assign(Place::Local(local), _) => {
+ if temps[local] == TempState::PromotedOut {
+ // Already promoted.
+ continue;
+ }
}
+ _ => {}
}
- (statement.source_info.span, dest.ty(mir, tcx).to_ty(tcx))
- }
- Candidate::Argument { bb, index } => {
- let terminator = mir[bb].terminator();
- let ty = match terminator.kind {
- TerminatorKind::Call { ref args, .. } => {
- args[index].ty(mir, tcx)
- }
- _ => {
- span_bug!(terminator.source_info.span,
- "expected call argument to promote");
- }
- };
- (terminator.source_info.span, ty)
}
- };
+ Candidate::Argument { .. } => {}
+ }
+
- // Declare return place local
- let initial_locals = iter::once(LocalDecl::new_return_place(ty, span))
- .collect();
+ // Declare return place local so that `Mir::new` doesn't complain.
+ let initial_locals = iter::once(
+ LocalDecl::new_return_place(tcx.types.never, mir.span)
+ ).collect();
let mut promoter = Promoter {
promoted: Mir::new(
initial_locals,
0,
vec![],
- span
+ mir.span
),
+ tcx,
source: mir,
temps: &mut temps,
+ extra_statements: &mut extra_statements,
keep_original: false
};
- assert_eq!(promoter.new_block(), START_BLOCK);
promoter.promote_candidate(candidate);
}
+ // Insert each of `extra_statements` before its indicated location, which
+ // has to be done in reverse location order, to not invalidate the rest.
+ extra_statements.sort_by_key(|&(loc, _)| cmp::Reverse(loc));
+ for (loc, statement) in extra_statements {
+ mir[loc.block].statements.insert(loc.statement_index, statement);
+ }
+
// Eliminate assignments to, and drops of promoted temps.
let promoted = |index: Local| temps[index] == TempState::PromotedOut;
for block in mir.basic_blocks_mut() {
}
/// Check if a Local with the current qualifications is promotable.
- fn can_promote(&mut self) -> bool {
+ fn can_promote(&self, qualif: Qualif) -> bool {
// References to statics are allowed, but only in other statics.
if self.mode == Mode::Static || self.mode == Mode::StaticMut {
- (self.qualif - Qualif::STATIC_REF).is_empty()
+ (qualif - Qualif::STATIC_REF).is_empty()
} else {
- self.qualif.is_empty()
+ qualif.is_empty()
}
}
}
let ty = place.ty(self.mir, self.tcx).to_ty(self.tcx);
+
+ // Default to forbidding the borrow and/or its promotion,
+ // due to the potential for direct or interior mutability,
+ // and only proceed by setting `forbidden_mut` to `false`.
+ let mut forbidden_mut = true;
+
if let BorrowKind::Mut { .. } = kind {
// In theory, any zero-sized value could be borrowed
// mutably without consequences. However, only &mut []
// is allowed right now, and only in functions.
- let allow = if self.mode == Mode::StaticMut {
+ if self.mode == Mode::StaticMut {
// Inside a `static mut`, &mut [...] is also allowed.
match ty.sty {
- ty::TyArray(..) | ty::TySlice(_) => true,
- _ => false
+ ty::TyArray(..) | ty::TySlice(_) => forbidden_mut = false,
+ _ => {}
}
} else if let ty::TyArray(_, len) = ty.sty {
- len.unwrap_usize(self.tcx) == 0 &&
- self.mode == Mode::Fn
- } else {
- false
- };
+ // FIXME(eddyb) the `self.mode == Mode::Fn` condition
+ // seems unnecessary, given that this is merely a ZST.
+ if len.unwrap_usize(self.tcx) == 0 && self.mode == Mode::Fn {
+ forbidden_mut = false;
+ }
+ }
- if !allow {
+ if forbidden_mut {
self.add(Qualif::NOT_CONST);
if self.mode != Mode::Fn {
let mut err = struct_span_err!(self.tcx.sess, self.span, E0017,
// it means that our "silent insertion of statics" could change
// initializer values (very bad).
if self.qualif.intersects(Qualif::MUTABLE_INTERIOR) {
- // Replace MUTABLE_INTERIOR with NOT_CONST to avoid
+ // A reference of a MUTABLE_INTERIOR place is instead
+ // NOT_CONST (see `if forbidden_mut` below), to avoid
// duplicate errors (from reborrowing, for example).
self.qualif = self.qualif - Qualif::MUTABLE_INTERIOR;
- self.add(Qualif::NOT_CONST);
if self.mode != Mode::Fn {
span_err!(self.tcx.sess, self.span, E0492,
"cannot borrow a constant which may contain \
interior mutability, create a static instead");
}
+ } else {
+ // We allow immutable borrows of frozen data.
+ forbidden_mut = false;
}
}
- // We might have a candidate for promotion.
- let candidate = Candidate::Ref(location);
- if self.can_promote() {
- // We can only promote direct borrows of temps.
+ if forbidden_mut {
+ self.add(Qualif::NOT_CONST);
+ } else {
+ // We might have a candidate for promotion.
+ let candidate = Candidate::Ref(location);
+ // We can only promote interior borrows of promotable temps.
+ let mut place = place;
+ while let Place::Projection(ref proj) = *place {
+ if proj.elem == ProjectionElem::Deref {
+ break;
+ }
+ place = &proj.base;
+ }
if let Place::Local(local) = *place {
if self.mir.local_kind(local) == LocalKind::Temp {
- self.promotion_candidates.push(candidate);
+ if let Some(qualif) = self.temp_qualif[local] {
+ // `forbidden_mut` is false, so we can safely ignore
+ // `MUTABLE_INTERIOR` from the local's qualifications.
+ // This allows borrowing fields which don't have
+ // `MUTABLE_INTERIOR`, from a type that does, e.g.:
+ // `let _: &'static _ = &(Cell::new(1), 2).1;`
+ if self.can_promote(qualif - Qualif::MUTABLE_INTERIOR) {
+ self.promotion_candidates.push(candidate);
+ }
+ }
}
}
}
}
let candidate = Candidate::Argument { bb, index: i };
if is_shuffle && i == 2 {
- if this.can_promote() {
+ if this.can_promote(this.qualif) {
this.promotion_candidates.push(candidate);
} else {
span_err!(this.tcx.sess, this.span, E0526,
if !constant_arguments.contains(&i) {
return
}
- if this.can_promote() {
+ if this.can_promote(this.qualif) {
this.promotion_candidates.push(candidate);
} else {
this.tcx.sess.span_err(this.span,
self.with_context(LabeledBlock, |v| v.visit_block(&b));
}
hir::ExprBreak(label, ref opt_expr) => {
+ opt_expr.as_ref().map(|e| self.visit_expr(e));
+
if self.require_label_in_labeled_block(e.span, &label, "break") {
// If we emitted an error about an unlabeled break in a labeled
// block, we don't need any further checking for this break any more
binding: &'a NameBinding<'a>,
directive: &'a ImportDirective<'a>,
used: Cell<bool>,
- legacy_self_import: bool,
},
Ambiguity {
b1: &'a NameBinding<'a>,
b2: &'a NameBinding<'a>,
- legacy: bool,
}
}
lexical: bool,
b1: &'a NameBinding<'a>,
b2: &'a NameBinding<'a>,
- legacy: bool,
}
impl<'a> NameBinding<'a> {
match self.kind {
NameBindingKind::Module(module) => Some(module),
NameBindingKind::Import { binding, .. } => binding.module(),
- NameBindingKind::Ambiguity { legacy: true, b1, .. } => b1.module(),
_ => None,
}
}
NameBindingKind::Def(def) => def,
NameBindingKind::Module(module) => module.def().unwrap(),
NameBindingKind::Import { binding, .. } => binding.def(),
- NameBindingKind::Ambiguity { legacy: true, b1, .. } => b1.def(),
NameBindingKind::Ambiguity { .. } => Def::Err,
}
}
fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>, span: Span)
-> bool /* true if an error was reported */ {
match binding.kind {
- NameBindingKind::Import { directive, binding, ref used, legacy_self_import }
+ NameBindingKind::Import { directive, binding, ref used }
if !used.get() => {
used.set(true);
directive.used.set(true);
- if legacy_self_import {
- self.warn_legacy_self_import(directive);
- return false;
- }
self.used_imports.insert((directive.id, ns));
self.add_to_glob_map(directive.id, ident);
self.record_use(ident, ns, binding, span)
}
NameBindingKind::Import { .. } => false,
- NameBindingKind::Ambiguity { b1, b2, legacy } => {
+ NameBindingKind::Ambiguity { b1, b2 } => {
self.ambiguity_errors.push(AmbiguityError {
- span: span, name: ident.name, lexical: false, b1: b1, b2: b2, legacy,
+ span, name: ident.name, lexical: false, b1, b2,
});
- if legacy {
- self.record_use(ident, ns, b1, span);
- }
- !legacy
+ true
}
_ => false
}
self.report_proc_macro_import(krate);
let mut reported_spans = FxHashSet();
- for &AmbiguityError { span, name, b1, b2, lexical, legacy } in &self.ambiguity_errors {
+ for &AmbiguityError { span, name, b1, b2, lexical } in &self.ambiguity_errors {
if !reported_spans.insert(span) { continue }
let participle = |binding: &NameBinding| {
if binding.is_import() { "imported" } else { "defined" }
format!("macro-expanded {} do not shadow when used in a macro invocation path",
if b1.is_import() { "imports" } else { "items" })
};
- if legacy {
- let id = match b2.kind {
- NameBindingKind::Import { directive, .. } => directive.id,
- _ => unreachable!(),
- };
- let mut span = MultiSpan::from_span(span);
- span.push_span_label(b1.span, msg1);
- span.push_span_label(b2.span, msg2);
- let msg = format!("`{}` is ambiguous", name);
- self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, &msg);
- } else {
- let mut err =
- struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name);
- err.span_note(b1.span, &msg1);
- match b2.def() {
- Def::Macro(..) if b2.span == DUMMY_SP =>
- err.note(&format!("`{}` is also a builtin macro", name)),
- _ => err.span_note(b2.span, &msg2),
- };
- err.note(¬e).emit();
- }
+
+ let mut err = struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name);
+ err.span_note(b1.span, &msg1);
+ match b2.def() {
+ Def::Macro(..) if b2.span == DUMMY_SP =>
+ err.note(&format!("`{}` is also a builtin macro", name)),
+ _ => err.span_note(b2.span, &msg2),
+ };
+ err.note(¬e).emit();
}
for &PrivacyError(span, name, binding) in &self.privacy_errors {
self.name_already_seen.insert(name, span);
}
- fn warn_legacy_self_import(&self, directive: &'a ImportDirective<'a>) {
- let (id, span) = (directive.id, directive.span);
- let msg = "`self` no longer imports values";
- self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
- }
-
fn check_proc_macro_attrs(&mut self, attrs: &[ast::Attribute]) {
if self.proc_macro_enabled { return; }
b1: shadower,
b2: binding,
lexical: true,
- legacy: false,
});
return potential_illegal_shadower;
}
lexical: false,
b1: binding,
b2: shadowed_glob,
- legacy: false,
});
}
}
binding,
directive,
used: Cell::new(false),
- legacy_self_import: false,
},
span: directive.span,
vis,
pub fn ambiguity(&self, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
-> &'a NameBinding<'a> {
self.arenas.alloc_name_binding(NameBinding {
- kind: NameBindingKind::Ambiguity { b1: b1, b2: b2, legacy: false },
+ kind: NameBindingKind::Ambiguity { b1, b2 },
vis: if b1.vis.is_at_least(b2.vis, self) { b1.vis } else { b2.vis },
span: b1.span,
expansion: Mark::root(),
binding,
directive,
used: Cell::new(false),
- legacy_self_import: false,
},
vis: directive.vis.get(),
span: directive.span,
};
let mut all_ns_err = true;
- let mut legacy_self_import = None;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
if let Ok(binding) = result[ns].get() {
all_ns_err = false;
Some(this.dummy_binding);
}
}
- } else if let Ok(binding) = this.resolve_ident_in_module(module,
- ident,
- ns,
- false,
- false,
- directive.span) {
- legacy_self_import = Some(directive);
- let binding = this.arenas.alloc_name_binding(NameBinding {
- kind: NameBindingKind::Import {
- binding,
- directive,
- used: Cell::new(false),
- legacy_self_import: true,
- },
- ..*binding
- });
- let _ = this.try_define(directive.parent, ident, ns, binding);
});
if all_ns_err {
- if let Some(directive) = legacy_self_import {
- self.warn_legacy_self_import(directive);
- return None;
- }
let mut all_ns_failed = true;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
match this.resolve_ident_in_module(module, ident, ns, false, true, span) {
err.emit();
}
}
- NameBindingKind::Ambiguity { b1, b2, .. }
- if b1.is_glob_import() && b2.is_glob_import() => {
- let (orig_b1, orig_b2) = match (&b1.kind, &b2.kind) {
- (&NameBindingKind::Import { binding: b1, .. },
- &NameBindingKind::Import { binding: b2, .. }) => (b1, b2),
- _ => continue,
- };
- let (b1, b2) = match (orig_b1.vis, orig_b2.vis) {
- (ty::Visibility::Public, ty::Visibility::Public) => continue,
- (ty::Visibility::Public, _) => (b1, b2),
- (_, ty::Visibility::Public) => (b2, b1),
- _ => continue,
- };
- resolution.binding = Some(self.arenas.alloc_name_binding(NameBinding {
- kind: NameBindingKind::Ambiguity { b1: b1, b2: b2, legacy: true }, ..*b1
- }));
- }
_ => {}
}
}
// Make sure that the linker/gcc really don't pull in anything, including
// default objects, libs, etc.
- base.pre_link_args_crt.insert(LinkerFlavor::Gcc, Vec::new());
- base.pre_link_args_crt.get_mut(&LinkerFlavor::Gcc).unwrap().push("-nostdlib".to_string());
+ base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-nostdlib".to_string());
// At least when this was tested, the linker would not add the
// `GNU_EH_FRAME` program header to executables generated, which is required
//
// Each target directory for musl has these object files included in it so
// they'll be included from there.
- base.pre_link_objects_exe_crt.push("crt1.o".to_string());
- base.pre_link_objects_exe_crt.push("crti.o".to_string());
- base.pre_link_objects_exe_crt_sys.push("crtbegin.o".to_string());
- base.post_link_objects_crt_sys.push("crtend.o".to_string());
- base.post_link_objects_crt.push("crtn.o".to_string());
+ base.pre_link_objects_exe.push("crt1.o".to_string());
+ base.pre_link_objects_exe.push("crti.o".to_string());
+ base.post_link_objects.push("crtn.o".to_string());
// These targets statically link libc by default
base.crt_static_default = true;
/// Linker to invoke
pub linker: Option<String>,
- /// Linker arguments that are passed *before* any user-defined libraries.
- pub pre_link_args: LinkArgs, // ... unconditionally
- pub pre_link_args_crt: LinkArgs, // ... when linking with a bundled crt
- /// Objects to link before all others, all except *_sys found within the
+ /// Linker arguments that are unconditionally passed *before* any
+ /// user-defined libraries.
+ pub pre_link_args: LinkArgs,
+ /// Objects to link before all others, always found within the
/// sysroot folder.
- pub pre_link_objects_exe: Vec<String>, // ... when linking an executable, unconditionally
- pub pre_link_objects_exe_crt: Vec<String>, // ... when linking an executable with a bundled crt
- pub pre_link_objects_exe_crt_sys: Vec<String>, // ... when linking an executable with a bundled
- // crt, from the system library search path
+ pub pre_link_objects_exe: Vec<String>, // ... when linking an executable
pub pre_link_objects_dll: Vec<String>, // ... when linking a dylib
/// Linker arguments that are unconditionally passed after any
/// user-defined but before post_link_objects. Standard platform
/// libraries that should be always be linked to, usually go here.
pub late_link_args: LinkArgs,
- /// Objects to link after all others, all except *_sys found within the
+ /// Objects to link after all others, always found within the
/// sysroot folder.
- pub post_link_objects: Vec<String>, // ... unconditionally
- pub post_link_objects_crt: Vec<String>, // ... when linking with a bundled crt
- pub post_link_objects_crt_sys: Vec<String>, // ... when linking with a bundled crt, from the
- // system library search path
+ pub post_link_objects: Vec<String>,
/// Linker arguments that are unconditionally passed *after* any
/// user-defined libraries.
pub post_link_args: LinkArgs,
is_builtin: false,
linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
pre_link_args: LinkArgs::new(),
- pre_link_args_crt: LinkArgs::new(),
post_link_args: LinkArgs::new(),
asm_args: Vec::new(),
cpu: "generic".to_string(),
position_independent_executables: false,
relro_level: RelroLevel::None,
pre_link_objects_exe: Vec::new(),
- pre_link_objects_exe_crt: Vec::new(),
- pre_link_objects_exe_crt_sys: Vec::new(),
pre_link_objects_dll: Vec::new(),
post_link_objects: Vec::new(),
- post_link_objects_crt: Vec::new(),
- post_link_objects_crt_sys: Vec::new(),
late_link_args: LinkArgs::new(),
link_env: Vec::new(),
archive_format: "gnu".to_string(),
key!(is_builtin, bool);
key!(linker, optional);
key!(pre_link_args, link_args);
- key!(pre_link_args_crt, link_args);
key!(pre_link_objects_exe, list);
- key!(pre_link_objects_exe_crt, list);
- key!(pre_link_objects_exe_crt_sys, list);
key!(pre_link_objects_dll, list);
key!(late_link_args, link_args);
key!(post_link_objects, list);
- key!(post_link_objects_crt, list);
- key!(post_link_objects_crt_sys, list);
key!(post_link_args, link_args);
key!(link_env, env);
key!(asm_args, list);
target_option_val!(is_builtin);
target_option_val!(linker);
target_option_val!(link_args - pre_link_args);
- target_option_val!(link_args - pre_link_args_crt);
target_option_val!(pre_link_objects_exe);
- target_option_val!(pre_link_objects_exe_crt);
- target_option_val!(pre_link_objects_exe_crt_sys);
target_option_val!(pre_link_objects_dll);
target_option_val!(link_args - late_link_args);
target_option_val!(post_link_objects);
- target_option_val!(post_link_objects_crt);
- target_option_val!(post_link_objects_crt_sys);
target_option_val!(link_args - post_link_args);
target_option_val!(env - link_env);
target_option_val!(asm_args);
-Subproject commit 1abfd0e562cc8f7a9577d97ee92246699093b954
+Subproject commit 56c931901cfb85cd6f7ed44c7d7520a8de1edf97
# If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
# The actual contents of this file do not matter, but to trigger a change on the
# build bots then the contents should be changed so git updates the mtime.
-2018-04-05
+2018-05-18
\ No newline at end of file
// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength
+// min-llvm-version 6.0
#![crate_type = "lib"]
#![feature(custom_attribute)]
pub fn unsafe_borrow(_: &UnsafeInner) {
}
-// CHECK: @mutable_unsafe_borrow(i16* dereferenceable(2) %arg0)
+// CHECK: @mutable_unsafe_borrow(i16* noalias dereferenceable(2) %arg0)
// ... unless this is a mutable borrow, those never alias
-// ... except that there's this LLVM bug that forces us to not use noalias, see #29485
#[no_mangle]
pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {
}
-// CHECK: @mutable_borrow(i32* dereferenceable(4) %arg0)
+// CHECK: @mutable_borrow(i32* noalias dereferenceable(4) %arg0)
// FIXME #25759 This should also have `nocapture`
-// ... there's this LLVM bug that forces us to not use noalias, see #29485
#[no_mangle]
pub fn mutable_borrow(_: &mut i32) {
}
pub fn slice(_: &[u8]) {
}
-// CHECK: @mutable_slice([0 x i8]* nonnull %arg0.0, [[USIZE]] %arg0.1)
+// CHECK: @mutable_slice([0 x i8]* noalias nonnull %arg0.0, [[USIZE]] %arg0.1)
// FIXME #25759 This should also have `nocapture`
-// ... there's this LLVM bug that forces us to not use noalias, see #29485
#[no_mangle]
pub fn mutable_slice(_: &mut [u8]) {
}
// Test that `fn foo::bar::{self}` only imports `bar` in the type namespace.
-#![allow(unused)]
-
mod foo {
pub fn f() { }
}
-use foo::f::{self};
-//~^ ERROR `self` no longer imports values
-//~| WARN hard error
+use foo::f::{self}; //~ ERROR unresolved import `foo::f`
mod bar {
pub fn baz() {}
pub mod baz {}
}
use bar::baz::{self};
-//~^ ERROR `self` no longer imports values
-//~| WARN hard error
fn main() {
- baz();
+ baz(); //~ ERROR expected function, found module `baz`
}
// let mut _7: &'10s S1;
// let mut _8: &'10s S1;
// let mut _9: S1;
+// let mut _10: &'10s S1;
+// let mut _11: &'12ds S1;
//
// bb0: {
// StorageLive(_2);
// StorageLive(_3);
// StorageLive(_4);
// StorageLive(_5);
-// _5 = promoted[1];
+// _11 = promoted[1];
+// _5 = &'12ds (*_11);
// _4 = &'12ds (*_5);
// StorageLive(_7);
// StorageLive(_8);
-// _8 = promoted[0];
+// _10 = promoted[0];
+// _8 = &'10s (*_10);
// _7 = &'10s (*_8);
// _3 = D1<'12ds, '10s>::{{constructor}}(move _4, move _7);
// EndRegion('10s);
// }
// bb9: { // binding1 and guard
// StorageLive(_5);
-// _5 = &((_2 as Some).0: i32);
+// _11 = promoted[0];
+// _5 = &(((*_11) as Some).0: i32);
// StorageLive(_8);
// _8 = const guard() -> [return: bb10, unwind: bb1];
// }
+++ /dev/null
--include ../tools.mk
-
-all: foo
- $(call RUN,foo)
-
-foo: foo.rs $(call NATIVE_STATICLIB,foo)
- $(RUSTC) $< -lfoo $(EXTRACXXFLAGS)
-
-$(TMPDIR)/libfoo.o: foo.cpp
- $(call COMPILE_OBJ_CXX,$@,$<)
-
-.PHONY: all
+++ /dev/null
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#include <stdint.h>
-
-struct A {
- A() { v = 1234; }
- ~A() { v = 1; }
- uint32_t v;
-};
-
-A a;
-
-extern "C" {
- uint32_t get() {
- return a.v;
- }
-}
+++ /dev/null
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Tests that linking to C++ code with global destructors works.
-
-extern { fn get() -> u32; }
-
-fn main() {
- let i = unsafe { get() };
- assert_eq!(i, 1234);
-}
ifdef IS_MSVC
COMPILE_OBJ = $(CC) -c -Fo:`cygpath -w $(1)` $(2)
-COMPILE_OBJ_CXX = $(CXX) -c -Fo:`cygpath -w $(1)` $(2)
NATIVE_STATICLIB_FILE = $(1).lib
NATIVE_STATICLIB = $(TMPDIR)/$(call NATIVE_STATICLIB_FILE,$(1))
OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
-Fo:`cygpath -w $(TMPDIR)/$(1).obj`
else
COMPILE_OBJ = $(CC) -c -o $(1) $(2)
-COMPILE_OBJ_CXX = $(CXX) -c -o $(1) $(2)
NATIVE_STATICLIB_FILE = lib$(1).a
NATIVE_STATICLIB = $(call STATICLIB,$(1))
OUT_EXE=-o $(TMPDIR)/$(1)
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Z borrowck=mir
+
+use std::cell::Cell;
+
+#[inline(never)]
+fn tuple_field() -> &'static u32 {
+ // This test is MIR-borrowck-only because the old borrowck
+ // doesn't agree that borrows of "frozen" (i.e. without any
+ // interior mutability) fields of non-frozen temporaries,
+ // should be promoted, while MIR promotion does promote them.
+ &(Cell::new(5), 42).1
+}
+
+fn main() {
+ assert_eq!(tuple_field().to_string(), "42");
+}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Z borrowck=compare
+
+const ALL_THE_NUMS: [u32; 1] = [
+ 1
+];
+
+#[inline(never)]
+fn array(i: usize) -> &'static u32 {
+ return &ALL_THE_NUMS[i];
+}
+
+#[inline(never)]
+fn tuple_field() -> &'static u32 {
+ &(42,).0
+}
+
+fn main() {
+ assert_eq!(tuple_field().to_string(), "42");
+ assert_eq!(array(0).to_string(), "1");
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unused)]
-
pub struct Foo;
mod bar {
mod baz {
use *;
use bar::*;
- fn f(_: Foo) {}
- //~^ ERROR `Foo` is ambiguous
- //~| WARN hard error in a future release
+ fn f(_: Foo) {} //~ ERROR `Foo` is ambiguous
}
}
-error: `Foo` is ambiguous
- --> $DIR/rfc-1560-warning-cycle.rs:21:17
+error[E0659]: `Foo` is ambiguous
+ --> $DIR/rfc-1560-warning-cycle.rs:19:17
|
-LL | use *;
- | - `Foo` could refer to the name imported here
-LL | use bar::*;
- | ------ `Foo` could also refer to the name imported here
-LL | fn f(_: Foo) {}
+LL | fn f(_: Foo) {} //~ ERROR `Foo` is ambiguous
| ^^^
|
- = note: #[deny(legacy_imports)] on by default
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #38260 <https://github.com/rust-lang/rust/issues/38260>
+note: `Foo` could refer to the name imported here
+ --> $DIR/rfc-1560-warning-cycle.rs:17:13
+ |
+LL | use *;
+ | ^
+note: `Foo` could also refer to the name imported here
+ --> $DIR/rfc-1560-warning-cycle.rs:18:13
+ |
+LL | use bar::*;
+ | ^^^^^^
+ = note: consider adding an explicit import of `Foo` to disambiguate
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0659`.
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[allow(unreachable_code)]
+
+fn main() {
+ loop {
+ break while continue { //~ ERROR E0590
+ }
+ }
+}
--- /dev/null
+error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+ --> $DIR/issue-50802.rs:15:21
+ |
+LL | break while continue { //~ ERROR E0590
+ | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0590`.
endless_and_singing: bool
}
+struct LovelyAmbition {
+ lips: usize,
+ fire: usize
+}
+
#[derive(Clone, Copy)]
enum Large {
Suit { case: () }
hours_are_suns = false;
}
+ let the_spirit = LovelyAmbition { lips: 1, fire: 2 };
+ let LovelyAmbition { lips, fire } = the_spirit;
+ println!("{}", lips);
+
let bag = Large::Suit {
case: ()
};
warning: unused variable: `i_think_continually`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:31:9
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:36:9
|
LL | let i_think_continually = 2;
| ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
= note: #[warn(unused_variables)] implied by #[warn(unused)]
warning: unused variable: `mut_unused_var`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:13
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:13
|
LL | let mut mut_unused_var = 1;
| ^^^^^^^^^^^^^^ help: consider using `_mut_unused_var` instead
warning: unused variable: `var`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:14
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:14
|
LL | let (mut var, unused_var) = (1, 2);
| ^^^ help: consider using `_var` instead
warning: unused variable: `unused_var`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:19
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:19
|
LL | let (mut var, unused_var) = (1, 2);
| ^^^^^^^^^^ help: consider using `_unused_var` instead
warning: unused variable: `corridors_of_light`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:42:26
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:47:26
|
LL | if let SoulHistory { corridors_of_light,
| ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
warning: variable `hours_are_suns` is assigned to, but never used
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:30
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:48:30
|
LL | mut hours_are_suns,
| ^^^^^^^^^^^^^^
= note: consider using `_hours_are_suns` instead
warning: value assigned to `hours_are_suns` is never read
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:9
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:9
|
LL | hours_are_suns = false;
| ^^^^^^^^^^^^^^
| ^^^^^^
= note: #[warn(unused_assignments)] implied by #[warn(unused)]
+warning: unused variable: `fire`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:54:32
+ |
+LL | let LovelyAmbition { lips, fire } = the_spirit;
+ | ^^^^ help: try ignoring the field: `fire: _`
+
warning: unused variable: `case`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:54:23
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:63:23
|
LL | Large::Suit { case } => {}
| ^^^^ help: try ignoring the field: `case: _`
warning: unused variable: `case`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:59:24
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:68:24
|
LL | &Large::Suit { case } => {}
| ^^^^ help: try ignoring the field: `case: _`
warning: unused variable: `case`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:64:27
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:73:27
|
LL | box Large::Suit { case } => {}
| ^^^^ help: try ignoring the field: `case: _`
warning: unused variable: `case`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:69:24
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:78:24
|
LL | (Large::Suit { case },) => {}
| ^^^^ help: try ignoring the field: `case: _`
warning: unused variable: `case`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:74:24
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:83:24
|
LL | [Large::Suit { case }] => {}
| ^^^^ help: try ignoring the field: `case: _`
warning: unused variable: `case`
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:79:29
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:88:29
|
LL | Tuple(Large::Suit { case }, ()) => {}
| ^^^^ help: try ignoring the field: `case: _`
warning: variable does not need to be mutable
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:9
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:9
|
LL | let mut mut_unused_var = 1;
| ----^^^^^^^^^^^^^^
= note: #[warn(unused_mut)] implied by #[warn(unused)]
warning: variable does not need to be mutable
- --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:10
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:10
|
LL | let (mut var, unused_var) = (1, 2);
| ----^^^
.env("IS_WINDOWS", "1")
.env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
.env("CC", format!("'{}' {}", self.config.cc, cflags))
- .env("CXX", format!("'{}'", &self.config.cxx));
+ .env("CXX", &self.config.cxx);
} else {
cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
.env("CXX", format!("{} {}", self.config.cxx, self.config.cflags))