"env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "flate2"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
dependencies = [
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "racer"
-version = "2.1.6"
+version = "2.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "racer 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "racer 2.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fmt_macros 0.0.0",
"graphviz 0.0.0",
"jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
name = "rustc_codegen_utils"
version = "0.0.0"
dependencies = [
- "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_data_structures 0.0.0",
name = "rustc_metadata"
version = "0.0.0"
dependencies = [
- "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"proc_macro 0.0.0",
"rustc 0.0.0",
"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426"
"checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
-"checksum flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37847f133aae7acf82bb9577ccd8bda241df836787642654286e79679826a54b"
+"checksum flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4af030962d89d62aa52cd9492083b1cd9b2d1a77764878102a6c0f86b4d5444d"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
-"checksum racer 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "99e820b7f7701c834c3f6f8226f388c19c0ea948a3ef79ddc96aa7398b5ba87a"
+"checksum racer 2.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0beefbfaed799c3554021a48856113ad53862311395f6d75376192884ba5fbe6"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
builder.install(&cargoclippy, &image.join("bin"), 0o755);
let doc = image.join("share/doc/clippy");
builder.install(&src.join("README.md"), &doc, 0o644);
- builder.install(&src.join("LICENSE"), &doc, 0o644);
+ builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
+ builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
// Prepare the overlay
let overlay = tmp.join("clippy-overlay");
drop(fs::remove_dir_all(&overlay));
t!(fs::create_dir_all(&overlay));
builder.install(&src.join("README.md"), &overlay, 0o644);
- builder.install(&src.join("LICENSE"), &doc, 0o644);
+ builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
+ builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
builder.create(&overlay.join("version"), &version);
// Generate the installer tarball
t!(fs::create_dir_all(dstdir));
drop(fs::remove_file(&dst));
{
+ if !src.exists() {
+ panic!("Error: File \"{}\" not found!", src.display());
+ }
let mut s = t!(fs::File::open(&src));
let mut d = t!(fs::File::create(&dst));
io::copy(&mut s, &mut d).expect("failed to copy");
//! Additionally, the return value of this function is [`fmt::Result`] which is a
//! type alias of [`Result`]`<(), `[`std::fmt::Error`]`>`. Formatting implementations
//! should ensure that they propagate errors from the [`Formatter`][`Formatter`] (e.g., when
-//! calling [`write!`]) however, they should never return errors spuriously. That
+//! calling [`write!`]). However, they should never return errors spuriously. That
//! is, a formatting implementation must and may only return an error if the
//! passed-in [`Formatter`] returns an error. This is because, contrary to what
//! the function signature might suggest, string formatting is an infallible
///
/// let five = Rc::new(5);
///
- /// Rc::clone(&five);
+ /// let _ = Rc::clone(&five);
/// ```
#[inline]
fn clone(&self) -> Rc<T> {
///
/// let weak_five = Rc::downgrade(&Rc::new(5));
///
- /// Weak::clone(&weak_five);
+ /// let _ = Weak::clone(&weak_five);
/// ```
#[inline]
fn clone(&self) -> Weak<T> {
///
/// let five = Arc::new(5);
///
- /// Arc::clone(&five);
+ /// let _ = Arc::clone(&five);
/// ```
#[inline]
fn clone(&self) -> Arc<T> {
///
/// let weak_five = Arc::downgrade(&Arc::new(5));
///
- /// Weak::clone(&weak_five);
+ /// let _ = Weak::clone(&weak_five);
/// ```
#[inline]
fn clone(&self) -> Weak<T> {
match ty.sty {
ty::Ref(..) => true,
ty::Adt(def, _) => def.is_fundamental(),
- ty::Dynamic(ref data, ..) => {
- data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental"))
- }
+ ty::Dynamic(ref data, ..) => tcx.has_attr(data.principal().def_id(), "fundamental"),
_ => false
}
}
ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
ty::Foreign(did) => def_id_is_local(did, in_crate),
- ty::Dynamic(ref tt, ..) => {
- tt.principal().map_or(false, |p|
- def_id_is_local(p.def_id(), in_crate)
- )
- }
+ ty::Dynamic(ref tt, ..) => def_id_is_local(tt.principal().def_id(), in_crate),
ty::Error => true,
return;
}
- match data.principal() {
- Some(p) => p.with_self_ty(this.tcx(), self_ty),
- None => return,
- }
+ data.principal().with_self_ty(this.tcx(), self_ty)
}
ty::Infer(ty::TyVar(_)) => {
debug!("assemble_candidates_from_object_ty: ambiguous");
//
// We always upcast when we can because of reason
// #2 (region bounds).
- match (data_a.principal(), data_b.principal()) {
- (Some(a), Some(b)) => {
- a.def_id() == b.def_id()
- && data_b.auto_traits()
- // All of a's auto traits need to be in b's auto traits.
- .all(|b| data_a.auto_traits().any(|a| a == b))
- }
- _ => false,
- }
+ data_a.principal().def_id() == data_b.principal().def_id()
+ && data_b.auto_traits()
+ // All of a's auto traits need to be in b's auto traits.
+ .all(|b| data_a.auto_traits().any(|a| a == b))
}
// T -> Trait.
.shallow_resolve(*obligation.self_ty().skip_binder());
let poly_trait_ref = match self_ty.sty {
ty::Dynamic(ref data, ..) => {
- data.principal().unwrap().with_self_ty(self.tcx(), self_ty)
+ data.principal().with_self_ty(self.tcx(), self_ty)
}
_ => span_bug!(obligation.cause.span, "object candidate with non-object"),
};
(&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
// See assemble_candidates_for_unsizing for more info.
let existential_predicates = data_a.map_bound(|data_a| {
- let principal = data_a.principal();
- let iter = principal
- .into_iter()
- .map(ty::ExistentialPredicate::Trait)
+ let iter = iter::once(ty::ExistentialPredicate::Trait(data_a.principal()))
.chain(
data_a
.projection_bounds()
// T -> Trait.
(_, &ty::Dynamic(ref data, r)) => {
let mut object_dids = data.auto_traits()
- .chain(data.principal().map(|p| p.def_id()));
+ .chain(iter::once(data.principal().def_id()));
if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
return Err(TraitNotObjectSafe(did));
}
ty::FnDef(..) => "fn item".into(),
ty::FnPtr(_) => "fn pointer".into(),
ty::Dynamic(ref inner, ..) => {
- inner.principal().map_or_else(|| "trait".into(),
- |p| format!("trait {}", tcx.item_path_str(p.def_id())).into())
+ format!("trait {}", tcx.item_path_str(inner.principal().def_id())).into()
}
ty::Closure(..) => "closure".into(),
ty::Generator(..) => "generator".into(),
ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType),
ty::RawPtr(_) => Some(PtrSimplifiedType),
ty::Dynamic(ref trait_info, ..) => {
- trait_info.principal().map(|p| TraitSimplifiedType(p.def_id()))
+ Some(TraitSimplifiedType(trait_info.principal().def_id()))
}
ty::Ref(_, ty, _) => {
// since we introduce auto-refs during method lookup, we
match ty.sty {
ty::Adt(adt_def, _) => Some(adt_def.did),
- ty::Dynamic(data, ..) => data.principal().map(|p| p.def_id()),
+ ty::Dynamic(data, ..) => Some(data.principal().def_id()),
ty::Array(subty, _) |
ty::Slice(subty) => characteristic_def_id_of_type(subty),
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}
impl<'tcx> List<ExistentialPredicate<'tcx>> {
- pub fn principal(&self) -> Option<ExistentialTraitRef<'tcx>> {
- match self.get(0) {
- Some(&ExistentialPredicate::Trait(tr)) => Some(tr),
- _ => None,
+ pub fn principal(&self) -> ExistentialTraitRef<'tcx> {
+ match self[0] {
+ ExistentialPredicate::Trait(tr) => tr,
+ other => bug!("first predicate is {:?}", other),
}
}
}
impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
- pub fn principal(&self) -> Option<PolyExistentialTraitRef<'tcx>> {
- self.skip_binder().principal().map(Binder::bind)
+ pub fn principal(&self) -> PolyExistentialTraitRef<'tcx> {
+ Binder::bind(self.skip_binder().principal())
}
#[inline]
}
Dynamic(ref obj, region) => {
let mut v = vec![region];
- if let Some(p) = obj.principal() {
- v.extend(p.skip_binder().substs.regions());
- }
+ v.extend(obj.principal().skip_binder().substs.regions());
v
}
Adt(_, substs) | Opaque(_, substs) => {
let cause = self.cause(traits::MiscObligation);
let component_traits =
- data.auto_traits().chain(data.principal().map(|p| p.def_id()));
+ data.auto_traits().chain(once(data.principal().def_id()));
self.out.extend(
component_traits.map(|did| traits::Obligation::new(
cause.clone(),
// Use a type that can't appear in defaults of type parameters.
let dummy_self = tcx.mk_infer(ty::FreshTy(0));
- if let Some(p) = self.principal() {
- let principal = tcx.lift(&p).expect("could not lift TraitRef for printing")
- .with_self_ty(tcx, dummy_self);
- let projections = self.projection_bounds().map(|p| {
- tcx.lift(&p)
- .expect("could not lift projection for printing")
- .with_self_ty(tcx, dummy_self)
- }).collect::<Vec<_>>();
- cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
- }
+ let principal = tcx
+ .lift(&self.principal())
+ .expect("could not lift TraitRef for printing")
+ .with_self_ty(tcx, dummy_self);
+ let projections = self.projection_bounds().map(|p| {
+ tcx.lift(&p)
+ .expect("could not lift projection for printing")
+ .with_self_ty(tcx, dummy_self)
+ }).collect::<Vec<_>>();
+ cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
// Builtin bounds.
for did in self.auto_traits() {
/// Cache instances of monomorphic and polymorphic items
pub instances: RefCell<FxHashMap<Instance<'tcx>, &'a Value>>,
/// Cache generated vtables
- pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>),
+ pub vtables: RefCell<FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>),
&'a Value>>,
/// Cache of constant strings,
pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'a Value>>,
// But it does not describe the trait's methods.
let containing_scope = match trait_type.sty {
- ty::Dynamic(ref data, ..) => if let Some(principal) = data.principal() {
- let def_id = principal.def_id();
- Some(get_namespace_for_item(cx, def_id))
- } else {
- NO_SCOPE_METADATA
- },
+ ty::Dynamic(ref data, ..) => Some(get_namespace_for_item(cx, data.principal().def_id())),
_ => {
bug!("debuginfo: Unexpected trait-object type in \
trait_pointer_metadata(): {:?}",
}
},
ty::Dynamic(ref trait_data, ..) => {
- if let Some(principal) = trait_data.principal() {
- let principal = cx.tcx.normalize_erasing_late_bound_regions(
- ty::ParamEnv::reveal_all(),
- &principal,
- );
- push_item_name(cx, principal.def_id, false, output);
- push_type_params(cx, principal.substs, output);
- }
+ let principal = cx.tcx.normalize_erasing_late_bound_regions(
+ ty::ParamEnv::reveal_all(),
+ &trait_data.principal(),
+ );
+ push_item_name(cx, principal.def_id, false, output);
+ push_type_params(cx, principal.substs, output);
},
ty::FnDef(..) | ty::FnPtr(_) => {
let sig = t.fn_sig(cx.tcx);
pub fn get_vtable(
cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>,
- trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+ trait_ref: ty::PolyExistentialTraitRef<'tcx>,
) -> &'ll Value {
let tcx = cx.tcx;
// Not in the cache. Build it.
let nullptr = C_null(Type::i8p(cx));
+ let methods = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty));
+ let methods = methods.iter().cloned().map(|opt_mth| {
+ opt_mth.map_or(nullptr, |(def_id, substs)| {
+ callee::resolve_and_get_fn(cx, def_id, substs)
+ })
+ });
+
let (size, align) = cx.size_and_align_of(ty);
- let mut components: Vec<_> = [
+ let components: Vec<_> = [
callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)),
C_usize(cx, size.bytes()),
C_usize(cx, align.abi())
- ].iter().cloned().collect();
-
- if let Some(trait_ref) = trait_ref {
- let trait_ref = trait_ref.with_self_ty(tcx, ty);
- let methods = tcx.vtable_methods(trait_ref);
- let methods = methods.iter().cloned().map(|opt_mth| {
- opt_mth.map_or(nullptr, |(def_id, substs)| {
- callee::resolve_and_get_fn(cx, def_id, substs)
- })
- });
- components.extend(methods);
- }
+ ].iter().cloned().chain(methods).collect();
let vtable_const = C_struct(cx, &components, false);
let align = cx.data_layout().pointer_align;
match callee.node {
hir::ExprKind::Path(ref qpath) => {
let def = cx.tables.qpath_def(qpath, callee.hir_id);
- if let Def::Fn(_) = def {
- Some(def)
- } else { // `Def::Local` if it was a closure, for which we
- None // do not currently support must-use linting
+ match def {
+ Def::Fn(_) | Def::Method(_) => Some(def),
+ // `Def::Local` if it was a closure, for which we
+ // do not currently support must-use linting
+ _ => None
}
},
_ => None
}
(_, &ty::Dynamic(ref data, _)) => {
// Initial cast from sized to dyn trait
- let trait_ref = data.principal().unwrap().with_self_ty(
+ let trait_ref = data.principal().with_self_ty(
*self.tcx,
src_pointee_ty,
);
!impl_ty.needs_subst() && !impl_ty.has_escaping_regions());
if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty {
- if let Some(principal) = trait_ty.principal() {
- let poly_trait_ref = principal.with_self_ty(tcx, impl_ty);
- assert!(!poly_trait_ref.has_escaping_regions());
-
- // Walk all methods of the trait, including those of its supertraits
- let methods = tcx.vtable_methods(poly_trait_ref);
- let methods = methods.iter().cloned().filter_map(|method| method)
- .map(|(def_id, substs)| ty::Instance::resolve(
- tcx,
- ty::ParamEnv::reveal_all(),
- def_id,
- substs).unwrap())
- .filter(|&instance| should_monomorphize_locally(tcx, &instance))
- .map(|instance| create_fn_mono_item(instance));
- output.extend(methods);
- }
+ let poly_trait_ref = trait_ty.principal().with_self_ty(tcx, impl_ty);
+ assert!(!poly_trait_ref.has_escaping_regions());
+
+ // Walk all methods of the trait, including those of its supertraits
+ let methods = tcx.vtable_methods(poly_trait_ref);
+ let methods = methods.iter().cloned().filter_map(|method| method)
+ .map(|(def_id, substs)| ty::Instance::resolve(
+ tcx,
+ ty::ParamEnv::reveal_all(),
+ def_id,
+ substs).unwrap())
+ .filter(|&instance| should_monomorphize_locally(tcx, &instance))
+ .map(|instance| create_fn_mono_item(instance));
+ output.extend(methods);
// Also add the destructor
visit_drop_use(tcx, impl_ty, false, output);
}
output.push(']');
},
ty::Dynamic(ref trait_data, ..) => {
- if let Some(principal) = trait_data.principal() {
- self.push_def_path(principal.def_id(), output);
- self.push_type_params(principal.skip_binder().substs,
- trait_data.projection_bounds(),
- output);
- }
+ let principal = trait_data.principal();
+ self.push_def_path(principal.def_id(), output);
+ self.push_type_params(
+ principal.skip_binder().substs,
+ trait_data.projection_bounds(),
+ output,
+ );
},
ty::Foreign(did) => self.push_def_path(did, output),
ty::FnDef(..) |
let ty_def_id = match self.tcx.type_of(item_def_id).sty {
ty::Adt(adt, _) => adt.did,
ty::Foreign(did) => did,
- ty::Dynamic(ref obj, ..) if obj.principal().is_some() =>
- obj.principal().unwrap().def_id(),
+ ty::Dynamic(ref obj, ..) => obj.principal().def_id(),
ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id,
_ => return Some(AccessLevel::Public)
};
let ty_def_id = match ty.sty {
ty::Adt(adt, _) => Some(adt.did),
ty::Foreign(did) => Some(did),
- ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
+ ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()),
ty::Projection(ref proj) => Some(proj.item_def_id),
ty::FnDef(def_id, ..) |
ty::Closure(def_id, ..) |
let ty_def_id = match ty.sty {
ty::Adt(adt, _) => Some(adt.did),
ty::Foreign(did) => Some(did),
- ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
+ ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()),
ty::Projection(ref proj) => {
if self.required_visibility == ty::Visibility::Invisible {
// Conservatively approximate the whole type alias as public without
/// No metadata attached, ie pointer to sized type or foreign type
Thin,
/// A trait object
- Vtable(Option<DefId>),
+ Vtable(DefId),
/// Slice
Length,
/// The unsize info of this projection
Ok(match t.sty {
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
ty::Dynamic(ref tty, ..) =>
- Some(PointerKind::Vtable(tty.principal().map(|p| p.def_id()))),
+ Some(PointerKind::Vtable(tty.principal().def_id())),
ty::Adt(def, substs) if def.is_struct() => {
match def.non_enum_variant().fields.last() {
None => Some(PointerKind::Thin),
self.deduce_sig_from_projection(None, &pb)
})
.next();
- let kind = object_type
- .principal()
- .and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id()));
+ let kind = self.tcx.lang_items().fn_trait_kind(object_type.principal().def_id());
(sig, kind)
}
ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
.include_raw_pointers()
.filter_map(|(ty, _)|
match ty.sty {
- ty::Dynamic(ref data, ..) => data.principal().map(|p| closure(self, ty, p)),
+ ty::Dynamic(ref data, ..) => Some(closure(self, ty, data.principal())),
_ => None,
}
)
match self_ty.sty {
ty::Dynamic(ref data, ..) => {
- if let Some(p) = data.principal() {
- self.assemble_inherent_candidates_from_object(self_ty, p);
- self.assemble_inherent_impl_candidates_for_type(p.def_id());
- }
+ let p = data.principal();
+ self.assemble_inherent_candidates_from_object(self_ty, p);
+ self.assemble_inherent_impl_candidates_for_type(p.def_id());
}
ty::Adt(def, _) => {
self.assemble_inherent_impl_candidates_for_type(def.did);
ty::Adt(def, _) => def.did.is_local(),
ty::Foreign(did) => did.is_local(),
- ty::Dynamic(ref tr, ..) => tr.principal()
- .map_or(false, |p| p.def_id().is_local()),
+ ty::Dynamic(ref tr, ..) => tr.principal().def_id().is_local(),
ty::Param(_) => true,
ty::Foreign(did) => {
self.check_def_id(item, did);
}
- ty::Dynamic(ref data, ..) if data.principal().is_some() => {
- self.check_def_id(item, data.principal().unwrap().def_id());
+ ty::Dynamic(ref data, ..) => {
+ self.check_def_id(item, data.principal().def_id());
}
ty::Char => {
self.check_primitive_impl(def_id,
// This is something like impl Trait1 for Trait2. Illegal
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
- if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) {
+ if !tcx.is_object_safe(data.principal().def_id()) {
// This is an error, but it will be reported by wfcheck. Ignore it here.
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
} else {
let mut supertrait_def_ids =
- traits::supertrait_def_ids(tcx,
- data.principal().unwrap().def_id());
+ traits::supertrait_def_ids(tcx, data.principal().def_id());
if supertrait_def_ids.any(|d| d == trait_def_id) {
let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap());
struct_span_err!(tcx.sess,
debug!("Dynamic");
debug!("field_ty = {}", &field_ty);
debug!("ty in field = {}", &ty);
- if let Some(ex_trait_ref) = obj.principal() {
- // Here, we are passing the type `usize` as a
- // placeholder value with the function
- // `with_self_ty`, since there is no concrete type
- // `Self` for a `dyn Trait` at this
- // stage. Therefore when checking explicit
- // predicates in `check_explicit_predicates` we
- // need to ignore checking the explicit_map for
- // Self type.
- let substs = ex_trait_ref
- .with_self_ty(tcx, tcx.types.usize)
- .skip_binder()
- .substs;
- check_explicit_predicates(
- tcx,
- &ex_trait_ref.skip_binder().def_id,
- substs,
- required_predicates,
- explicit_map,
- IgnoreSelfTy(true),
- );
- }
+ let ex_trait_ref = obj.principal();
+ // Here, we are passing the type `usize` as a
+ // placeholder value with the function
+ // `with_self_ty`, since there is no concrete type
+ // `Self` for a `dyn Trait` at this
+ // stage. Therefore when checking explicit
+ // predicates in `check_explicit_predicates` we
+ // need to ignore checking the explicit_map for
+ // Self type.
+ let substs = ex_trait_ref
+ .with_self_ty(tcx, tcx.types.usize)
+ .skip_binder()
+ .substs;
+ check_explicit_predicates(
+ tcx,
+ &ex_trait_ref.skip_binder().def_id,
+ substs,
+ required_predicates,
+ explicit_map,
+ IgnoreSelfTy(true),
+ );
}
ty::Projection(obj) => {
let contra = self.contravariant(variance);
self.add_constraints_from_region(current, r, contra);
- if let Some(p) = data.principal() {
- let poly_trait_ref = p.with_self_ty(self.tcx(), self.tcx().types.err);
- self.add_constraints_from_trait_ref(
- current, *poly_trait_ref.skip_binder(), variance);
- }
+ let poly_trait_ref = data
+ .principal()
+ .with_self_ty(self.tcx(), self.tcx().types.err);
+ self.add_constraints_from_trait_ref(
+ current, *poly_trait_ref.skip_binder(), variance);
for projection in data.projection_bounds() {
self.add_constraints_from_ty(
}
}
ty::Dynamic(ref obj, ref reg) => {
- if let Some(principal) = obj.principal() {
- let did = principal.def_id();
+ let principal = obj.principal();
+ let did = principal.def_id();
+ inline::record_extern_fqn(cx, did, TypeKind::Trait);
+
+ let mut typarams = vec![];
+ reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b)));
+ for did in obj.auto_traits() {
+ let empty = cx.tcx.intern_substs(&[]);
+ let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
+ Some(did), false, vec![], empty);
inline::record_extern_fqn(cx, did, TypeKind::Trait);
+ let bound = GenericBound::TraitBound(PolyTrait {
+ trait_: ResolvedPath {
+ path,
+ typarams: None,
+ did,
+ is_generic: false,
+ },
+ generic_params: Vec::new(),
+ }, hir::TraitBoundModifier::None);
+ typarams.push(bound);
+ }
- let mut typarams = vec![];
- reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b)));
- for did in obj.auto_traits() {
- let empty = cx.tcx.intern_substs(&[]);
- let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
- Some(did), false, vec![], empty);
- inline::record_extern_fqn(cx, did, TypeKind::Trait);
- let bound = GenericBound::TraitBound(PolyTrait {
- trait_: ResolvedPath {
- path,
- typarams: None,
- did,
- is_generic: false,
- },
- generic_params: Vec::new(),
- }, hir::TraitBoundModifier::None);
- typarams.push(bound);
- }
-
- let mut bindings = vec![];
- for pb in obj.projection_bounds() {
- bindings.push(TypeBinding {
- name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx),
- ty: pb.skip_binder().ty.clean(cx)
- });
- }
+ let mut bindings = vec![];
+ for pb in obj.projection_bounds() {
+ bindings.push(TypeBinding {
+ name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx),
+ ty: pb.skip_binder().ty.clean(cx)
+ });
+ }
- let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did),
- false, bindings, principal.skip_binder().substs);
- ResolvedPath {
- path,
- typarams: Some(typarams),
- did,
- is_generic: false,
- }
- } else {
- Never
+ let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did),
+ false, bindings, principal.skip_binder().substs);
+ ResolvedPath {
+ path,
+ typarams: Some(typarams),
+ did,
+ is_generic: false,
}
}
ty::Tuple(ref t) => Tuple(t.clean(cx)),
force_alloc_system = []
panic-unwind = ["panic_unwind"]
profiler = ["profiler_builtins"]
+
+# An off-by-default feature which enables a linux-syscall-like ABI for libstd to
+# interoperate with the host environment. Currently not well documented and
+# requires rebuilding the standard library to use it.
wasm_syscall = []
+
+# An off-by-default features to enable libstd to assume that wasm-bindgen is in
+# the environment for hooking up some thread-related information like the
+# current thread id and accessing/getting the current thread's TCB
+wasm-bindgen-threads = []
use arch::wasm32::atomic;
use cell::UnsafeCell;
use mem;
-use sync::atomic::{AtomicUsize, AtomicU64, Ordering::SeqCst};
+use sync::atomic::{AtomicUsize, AtomicU32, Ordering::SeqCst};
+use sys::thread;
pub struct Mutex {
locked: AtomicUsize,
}
pub struct ReentrantMutex {
- owner: AtomicU64,
+ owner: AtomicU32,
recursions: UnsafeCell<u32>,
}
impl ReentrantMutex {
pub unsafe fn uninitialized() -> ReentrantMutex {
ReentrantMutex {
- owner: AtomicU64::new(0),
+ owner: AtomicU32::new(0),
recursions: UnsafeCell::new(0),
}
}
}
pub unsafe fn lock(&self) {
- let me = thread_id();
+ let me = thread::my_id();
while let Err(owner) = self._try_lock(me) {
- let val = atomic::wait_i64(self.ptr(), owner as i64, -1);
+ let val = atomic::wait_i32(self.ptr(), owner as i32, -1);
debug_assert!(val == 0 || val == 1);
}
}
#[inline]
pub unsafe fn try_lock(&self) -> bool {
- self._try_lock(thread_id()).is_ok()
+ self._try_lock(thread::my_id()).is_ok()
}
#[inline]
- unsafe fn _try_lock(&self, id: u64) -> Result<(), u64> {
+ unsafe fn _try_lock(&self, id: u32) -> Result<(), u32> {
let id = id.checked_add(1).unwrap(); // make sure `id` isn't 0
match self.owner.compare_exchange(0, id, SeqCst, SeqCst) {
// we transitioned from unlocked to locked
}
#[inline]
- fn ptr(&self) -> *mut i64 {
- &self.owner as *const AtomicU64 as *mut i64
+ fn ptr(&self) -> *mut i32 {
+ &self.owner as *const AtomicU32 as *mut i32
}
}
-
-fn thread_id() -> u64 {
- panic!("thread ids not implemented on wasm with atomics yet")
-}
pub unsafe fn init() -> Option<Guard> { None }
pub unsafe fn deinit() {}
}
+
+cfg_if! {
+ if #[cfg(all(target_feature = "atomics", feature = "wasm-bindgen-threads"))] {
+ #[link(wasm_import_module = "__wbindgen_thread_xform__")]
+ extern {
+ fn __wbindgen_current_id() -> u32;
+ fn __wbindgen_tcb_get() -> u32;
+ fn __wbindgen_tcb_set(ptr: u32);
+ }
+ pub fn my_id() -> u32 {
+ unsafe { __wbindgen_current_id() }
+ }
+
+ // These are currently only ever used in `thread_local_atomics.rs`, if
+ // you'd like to use them be sure to update that and make sure everyone
+ // agrees what's what.
+ pub fn tcb_get() -> *mut u8 {
+ use mem;
+ assert_eq!(mem::size_of::<*mut u8>(), mem::size_of::<u32>());
+ unsafe { __wbindgen_tcb_get() as *mut u8 }
+ }
+
+ pub fn tcb_set(ptr: *mut u8) {
+ unsafe { __wbindgen_tcb_set(ptr as u32); }
+ }
+
+ // FIXME: still need something for hooking exiting a thread to free
+ // data...
+
+ } else if #[cfg(target_feature = "atomics")] {
+ pub fn my_id() -> u32 {
+ panic!("thread ids not implemented on wasm with atomics yet")
+ }
+
+ pub fn tcb_get() -> *mut u8 {
+ panic!("thread local data not implemented on wasm with atomics yet")
+ }
+
+ pub fn tcb_set(ptr: *mut u8) {
+ panic!("thread local data not implemented on wasm with atomics yet")
+ }
+ } else {
+ // stubbed out because no functions actually access these intrinsics
+ // unless atomics are enabled
+ }
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use sys::thread;
+use sync::atomic::{AtomicUsize, Ordering::SeqCst};
+
+const MAX_KEYS: usize = 128;
+static NEXT_KEY: AtomicUsize = AtomicUsize::new(0);
+
+struct ThreadControlBlock {
+ keys: [*mut u8; MAX_KEYS],
+}
+
+impl ThreadControlBlock {
+ fn new() -> ThreadControlBlock {
+ ThreadControlBlock {
+ keys: [0 as *mut u8; MAX_KEYS],
+ }
+ }
+
+ fn get() -> *mut ThreadControlBlock {
+ let ptr = thread::tcb_get();
+ if !ptr.is_null() {
+ return ptr as *mut ThreadControlBlock
+ }
+ let tcb = Box::into_raw(Box::new(ThreadControlBlock::new()));
+ thread::tcb_set(tcb as *mut u8);
+ tcb
+ }
+}
+
pub type Key = usize;
-pub unsafe fn create(_dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
- panic!("TLS on wasm with atomics not implemented yet");
+pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
+ drop(dtor); // FIXME: need to figure out how to hook thread exit to run this
+ let key = NEXT_KEY.fetch_add(1, SeqCst);
+ if key >= MAX_KEYS {
+ NEXT_KEY.store(MAX_KEYS, SeqCst);
+ panic!("cannot allocate space for more TLS keys");
+ }
+ // offset by 1 so we never hand out 0. This is currently required by
+ // `sys_common/thread_local.rs` where it can't cope with keys of value 0
+ // because it messes up the atomic management.
+ return key + 1
}
-pub unsafe fn set(_key: Key, _value: *mut u8) {
- panic!("TLS on wasm with atomics not implemented yet");
+pub unsafe fn set(key: Key, value: *mut u8) {
+ (*ThreadControlBlock::get()).keys[key - 1] = value;
}
-pub unsafe fn get(_key: Key) -> *mut u8 {
- panic!("TLS on wasm with atomics not implemented yet");
+pub unsafe fn get(key: Key) -> *mut u8 {
+ (*ThreadControlBlock::get()).keys[key - 1]
}
pub unsafe fn destroy(_key: Key) {
- panic!("TLS on wasm with atomics not implemented yet");
+ // FIXME: should implement this somehow, this isn't typically called but it
+ // can be called if two threads race to initialize a TLS slot and one ends
+ // up not being needed.
}
#[inline]
&'static $crate::cell::UnsafeCell<
$crate::option::Option<$t>>>
{
- #[cfg(target_arch = "wasm32")]
+ #[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
static __KEY: $crate::thread::__StaticLocalKeyInner<$t> =
$crate::thread::__StaticLocalKeyInner::new();
#[thread_local]
- #[cfg(all(target_thread_local, not(target_arch = "wasm32")))]
+ #[cfg(all(
+ target_thread_local,
+ not(all(target_arch = "wasm32", not(target_feature = "atomics"))),
+ ))]
static __KEY: $crate::thread::__FastLocalKeyInner<$t> =
$crate::thread::__FastLocalKeyInner::new();
- #[cfg(all(not(target_thread_local), not(target_arch = "wasm32")))]
+ #[cfg(all(
+ not(target_thread_local),
+ not(all(target_arch = "wasm32", not(target_feature = "atomics"))),
+ ))]
static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
$crate::thread::__OsLocalKeyInner::new();
/// On some platforms like wasm32 there's no threads, so no need to generate
/// thread locals and we can instead just use plain statics!
#[doc(hidden)]
-#[cfg(target_arch = "wasm32")]
+#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
pub mod statik {
use cell::UnsafeCell;
use fmt;
// where available, but both are needed.
#[unstable(feature = "libstd_thread_internals", issue = "0")]
-#[cfg(target_arch = "wasm32")]
+#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
#[doc(hidden)] pub use self::local::statik::Key as __StaticLocalKeyInner;
#[unstable(feature = "libstd_thread_internals", issue = "0")]
#[cfg(target_thread_local)]
// #[cfg_attr(predicate, multiple, attributes, here)]
(active, cfg_attr_multi, "1.31.0", Some(54881), None),
+
+ // Allows `const _: TYPE = VALUE`
+ (active, underscore_const_names, "1.31.0", Some(54912), None),
);
declare_features! (
}
}
+ ast::ItemKind::Const(_,_) => {
+ if i.ident.name == "_" {
+ gate_feature_post!(&self, underscore_const_names, i.span,
+ "naming constants with `_` is unstable");
+ }
+ }
+
ast::ItemKind::ForeignMod(ref foreign_module) => {
self.check_abi(foreign_module.abi, i.span);
}
}
fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
- let id = self.parse_ident()?;
+ let id = match self.token {
+ token::Ident(ident, false) if ident.name == keywords::Underscore.name() => {
+ self.bump(); // `_`
+ ident.gensym()
+ },
+ _ => self.parse_ident()?,
+ };
self.expect(&token::Colon)?;
let ty = self.parse_ty()?;
self.expect(&token::Eq)?;
# source tarball for a stable release you'll likely see `1.x.0` for rustc and
# `0.x.0` for Cargo where they were released on `date`.
-date: 2018-09-23
+date: 2018-10-13
rustc: beta
cargo: beta
fn check<Clone>(_c: Clone) {
fn check2() {
- <() as std::clone::Clone>::clone(&());
+ let _ = <() as std::clone::Clone>::clone(&());
}
check2();
}
+++ /dev/null
-See `src/test/run-pass/closure-expected-type`.
--- /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-pass
+
+fn test<F: Fn(&u64, &u64)>(f: F) {}
+
+fn main() {
+ test(|x, y | {});
+ test(|x:&u64, y:&u64| {});
+ test(|x:&u64, y | {});
+ test(|x, y:&u64| {});
+}
--- /dev/null
+// Copyright 2012-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.
+#![feature(const_let)]
+
+trait Trt {}
+struct Str {}
+
+impl Trt for Str {}
+
+const _ : () = {
+ use std::marker::PhantomData;
+ struct ImplementsTrait<T: Trt>(PhantomData<T>);
+ let _ = ImplementsTrait::<Str>(PhantomData);
+ ()
+};
+
+fn main() {}
--- /dev/null
+error[E0658]: naming constants with `_` is unstable (see issue #54912)
+ --> $DIR/feature-gate-underscore_const_names.rs:17:1
+ |
+LL | / const _ : () = {
+LL | | use std::marker::PhantomData;
+LL | | struct ImplementsTrait<T: Trt>(PhantomData<T>);
+LL | | let _ = ImplementsTrait::<Str>(PhantomData);
+LL | | ()
+LL | | };
+ | |__^
+ |
+ = help: add #![feature(underscore_const_names)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
fn need_to_use_this_method_value(&self) -> usize {
self.n
}
+
+ #[must_use]
+ fn need_to_use_this_associated_function_value() -> isize {
+ -1
+ }
}
trait EvenNature {
m.is_even(); // trait method!
//~^ WARN unused return value
+ MyStruct::need_to_use_this_associated_function_value();
+ //~^ WARN unused return value
+
m.replace(3); // won't warn (annotation needs to be in trait definition)
// comparison methods are `must_use`
warning: unused return value of `need_to_use_this_value` which must be used
- --> $DIR/fn_must_use.rs:60:5
+ --> $DIR/fn_must_use.rs:65:5
|
LL | need_to_use_this_value(); //~ WARN unused return value
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: it's important
warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used
- --> $DIR/fn_must_use.rs:65:5
+ --> $DIR/fn_must_use.rs:70:5
|
LL | m.need_to_use_this_method_value(); //~ WARN unused return value
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused return value of `EvenNature::is_even` which must be used
- --> $DIR/fn_must_use.rs:66:5
+ --> $DIR/fn_must_use.rs:71:5
|
LL | m.is_even(); // trait method!
| ^^^^^^^^^^^^
|
= note: no side effects
+warning: unused return value of `MyStruct::need_to_use_this_associated_function_value` which must be used
+ --> $DIR/fn_must_use.rs:74:5
+ |
+LL | MyStruct::need_to_use_this_associated_function_value();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
warning: unused return value of `std::cmp::PartialEq::eq` which must be used
- --> $DIR/fn_must_use.rs:72:5
+ --> $DIR/fn_must_use.rs:80:5
|
LL | 2.eq(&3); //~ WARN unused return value
| ^^^^^^^^^
warning: unused return value of `std::cmp::PartialEq::eq` which must be used
- --> $DIR/fn_must_use.rs:73:5
+ --> $DIR/fn_must_use.rs:81:5
|
LL | m.eq(&n); //~ WARN unused return value
| ^^^^^^^^^
warning: unused comparison which must be used
- --> $DIR/fn_must_use.rs:76:5
+ --> $DIR/fn_must_use.rs:84:5
|
LL | 2 == 3; //~ WARN unused comparison
| ^^^^^^
warning: unused comparison which must be used
- --> $DIR/fn_must_use.rs:77:5
+ --> $DIR/fn_must_use.rs:85:5
|
LL | m == n; //~ WARN unused comparison
| ^^^^^^
--- /dev/null
+error[E0596]: cannot borrow data in a `&` reference as mutable
+ --> $DIR/issue-52240.rs:9:27
+ |
+LL | if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) {
+ | ^^^^^^^^^^^ cannot borrow as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
--- /dev/null
+// issue-52240: Can turn immutable into mut with `ref mut`
+
+enum Foo {
+ Bar(i32),
+}
+
+fn main() {
+ let arr = vec!(Foo::Bar(0));
+ if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) {
+ //~^ ERROR cannot borrow field of immutable binding as mutable
+ *val = 9001;
+ }
+ match arr[0] {
+ Foo::Bar(ref s) => println!("{}", s)
+ }
+}
--- /dev/null
+error[E0596]: cannot borrow field of immutable binding as mutable
+ --> $DIR/issue-52240.rs:9:27
+ |
+LL | if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) {
+ | ^^^^^^^^^^^ cannot mutably borrow field of immutable binding
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
--- /dev/null
+// issue-54966: ICE returning an unknown type with impl FnMut
+
+fn generate_duration() -> Oper<impl FnMut()> {}
+//~^ ERROR cannot find type `Oper` in this scope
+
+fn main() {}
--- /dev/null
+error[E0412]: cannot find type `Oper` in this scope
+ --> $DIR/issue-54966.rs:3:27
+ |
+LL | fn generate_duration() -> Oper<impl FnMut()> {}
+ | ^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
--- /dev/null
+// Copyright 2012-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-pass
+
+#![feature(const_let)]
+#![feature(underscore_const_names)]
+
+trait Trt {}
+struct Str {}
+impl Trt for Str {}
+
+macro_rules! check_impl {
+ ($struct:ident,$trait:ident) => {
+ const _ : () = {
+ use std::marker::PhantomData;
+ struct ImplementsTrait<T: $trait>(PhantomData<T>);
+ let _ = ImplementsTrait::<$struct>(PhantomData);
+ ()
+ };
+ }
+}
+
+#[deny(unused)]
+const _ : () = ();
+
+const _ : i32 = 42;
+const _ : Str = Str{};
+
+check_impl!(Str, Trt);
+check_impl!(Str, Trt);
+
+fn main() {
+ check_impl!(Str, Trt);
+ check_impl!(Str, Trt);
+}
-Subproject commit ad6e5c0037d88602a1c95051e42b392ed5ffcbe8
+Subproject commit 5dbac98885199bbd7c0f189d7405b5523434d1e3
-Subproject commit 32b1d1fc157f71ed2f10b60fe28abe087a743618
+Subproject commit 9d3373137b74a403281b293b19ab9346773af073
-Subproject commit 15d4d4a5b0cf3c0155195f3322cc7a61148e5567
+Subproject commit 440a9855b73b6bf9b5345cf3a79565566f6ef345