diff --git a/RELEASES.md b/RELEASES.md
index 819c9184364fd..08470e731d8e7 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,16 @@
+Version 1.29.1 (2018-09-25)
+===========================
+
+Security Notes
+--------------
+
+- The standard library's `str::repeat` function contained an out of bounds write
+ caused by an integer overflow. This has been fixed by deterministically
+ panicking when an overflow happens.
+
+ Thank you to Scott McMurray for responsibily disclosing this vulnerability to
+ us.
+
Version 1.29.0 (2018-09-13)
==========================
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index d09a545aecfaf..0224560af4c76 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -293,21 +293,21 @@ where
}
#[unstable(feature = "pin", issue = "49150")]
-impl<'a, P: fmt::Debug> fmt::Debug for Pin
{
+impl fmt::Debug for Pin {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&self.pointer, f)
}
}
#[unstable(feature = "pin", issue = "49150")]
-impl<'a, P: fmt::Display> fmt::Display for Pin
{
+impl fmt::Display for Pin {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.pointer, f)
}
}
#[unstable(feature = "pin", issue = "49150")]
-impl<'a, P: fmt::Pointer> fmt::Pointer for Pin
{
+impl fmt::Pointer for Pin {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(&self.pointer, f)
}
@@ -319,10 +319,10 @@ impl<'a, P: fmt::Pointer> fmt::Pointer for Pin
{
// for other reasons, though, so we just need to take care not to allow such
// impls to land in std.
#[unstable(feature = "pin", issue = "49150")]
-impl<'a, P, U> CoerceUnsized> for Pin
+impl
CoerceUnsized> for Pin
where
P: CoerceUnsized,
{}
#[unstable(feature = "pin", issue = "49150")]
-impl<'a, P> Unpin for Pin
{}
+impl
Unpin for Pin
{}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 3c68b5a7ab116..3f1e8ee55286b 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -761,7 +761,7 @@ impl Default for TargetOptions {
}
impl Target {
- /// Given a function ABI, turn "System" into the correct ABI for this target.
+ /// Given a function ABI, turn it into the correct ABI for this target.
pub fn adjust_abi(&self, abi: Abi) -> Abi {
match abi {
Abi::System => {
@@ -771,6 +771,16 @@ impl Target {
Abi::C
}
},
+ // These ABI kinds are ignored on non-x86 Windows targets.
+ // See https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions
+ // and the individual pages for __stdcall et al.
+ Abi::Stdcall | Abi::Fastcall | Abi::Vectorcall | Abi::Thiscall => {
+ if self.options.is_like_windows && self.arch != "x86" {
+ Abi::C
+ } else {
+ abi
+ }
+ },
abi => abi
}
}
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 72502cda6e02d..95a4cb82cf3ec 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -147,7 +147,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
bound_region: ty::BrNamed(id, name)
}))
- // (*) -- not late-bound, won't change
+ // (*) -- not late-bound, won't change
}
None => {
@@ -167,8 +167,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
};
debug!("ast_region_to_region(lifetime={:?}) yields {:?}",
- lifetime,
- r);
+ lifetime,
+ r);
r
}
@@ -218,7 +218,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
span,
E0632,
"cannot provide explicit type parameters when `impl Trait` is \
- used in argument position."
+ used in argument position."
};
err.emit();
@@ -538,7 +538,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
// region with the current anon region binding (in other words,
// whatever & would get replaced with).
debug!("create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
- generic_args={:?})",
+ generic_args={:?})",
def_id, self_ty, generic_args);
let tcx = self.tcx();
@@ -609,7 +609,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
if default_needs_object_self(param) {
struct_span_err!(tcx.sess, span, E0393,
"the type parameter `{}` must be explicitly \
- specified",
+ specified",
param.name)
.span_label(span,
format!("missing reference to `{}`", param.name))
@@ -623,7 +623,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
self.normalize_ty(
span,
tcx.at(span).type_of(param.def_id)
- .subst_spanned(tcx, substs.unwrap(), Some(span))
+ .subst_spanned(tcx, substs.unwrap(), Some(span))
).into()
}
} else if infer_types {
@@ -850,7 +850,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
binding.span,
E0582,
"binding for associated type `{}` references lifetime `{}`, \
- which does not appear in the trait input types",
+ which does not appear in the trait input types",
binding.item_name, br_name)
.emit();
}
@@ -890,7 +890,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
ref_id,
binding.span,
&format!("associated type binding `{}` specified more than once",
- binding.item_name)
+ binding.item_name)
);
err.span_label(binding.span, "used more than once");
err.span_label(*prev_span, format!("first use of `{}`", binding.item_name));
@@ -993,7 +993,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
if !object_safety_violations.is_empty() {
tcx.report_object_safety_error(
span, principal.def_id(), object_safety_violations)
- .emit();
+ .emit();
return tcx.types.err;
}
@@ -1013,13 +1013,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
for item_def_id in associated_types {
let assoc_item = tcx.associated_item(item_def_id);
let trait_def_id = assoc_item.container.id();
- struct_span_err!(tcx.sess, span, E0191,
- "the value of the associated type `{}` (from the trait `{}`) must be specified",
- assoc_item.ident,
- tcx.item_path_str(trait_def_id))
- .span_label(span, format!(
- "missing associated type `{}` value", assoc_item.ident))
- .emit();
+ struct_span_err!(tcx.sess, span, E0191, "the value of the associated type `{}` \
+ (from the trait `{}`) must be specified",
+ assoc_item.ident,
+ tcx.item_path_str(trait_def_id))
+ .span_label(span, format!("missing associated type `{}` value",
+ assoc_item.ident))
+ .emit();
}
// Dedup auto traits so that `dyn Trait + Send + Send` is the same as `dyn Trait + Send`.
@@ -1031,12 +1031,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
iter::once(ty::ExistentialPredicate::Trait(*existential_principal.skip_binder()))
.chain(auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait))
.chain(existential_projections
- .map(|x| ty::ExistentialPredicate::Projection(*x.skip_binder())))
+ .map(|x| ty::ExistentialPredicate::Projection(*x.skip_binder())))
.collect::>();
v.sort_by(|a, b| a.stable_cmp(tcx, b));
let existential_predicates = ty::Binder::bind(tcx.mk_existential_predicates(v.into_iter()));
-
// Explicitly specified region bound. Use that.
let region_bound = if !lifetime.is_elided() {
self.ast_region_to_region(lifetime, None)
@@ -1071,7 +1070,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type")
.span_label(span, "ambiguous associated type")
.note(&format!("specify the type using the syntax `<{} as {}>::{}`",
- type_str, trait_str, name))
+ type_str, trait_str, name))
.emit();
}
@@ -1093,8 +1092,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
// Check that there is exactly one way to find an associated type with the
// correct name.
- let suitable_bounds =
- traits::transitive_bounds(tcx, &bounds)
+ let suitable_bounds = traits::transitive_bounds(tcx, &bounds)
.filter(|b| self.trait_defines_associated_type_named(b.def_id(), assoc_name));
let param_node_id = tcx.hir.as_local_node_id(ty_param_def_id).unwrap();
@@ -1109,10 +1107,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
// Checks that bounds contains exactly one element and reports appropriate
// errors otherwise.
fn one_bound_for_assoc_type(&self,
- mut bounds: I,
- ty_param_name: &str,
- assoc_name: ast::Ident,
- span: Span)
+ mut bounds: I,
+ ty_param_name: &str,
+ assoc_name: ast::Ident,
+ span: Span)
-> Result, ErrorReported>
where I: Iterator- >
{
@@ -1120,9 +1118,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
Some(bound) => bound,
None => {
struct_span_err!(self.tcx().sess, span, E0220,
- "associated type `{}` not found for `{}`",
- assoc_name,
- ty_param_name)
+ "associated type `{}` not found for `{}`",
+ assoc_name,
+ ty_param_name)
.span_label(span, format!("associated type `{}` not found", assoc_name))
.emit();
return Err(ErrorReported);
@@ -1141,14 +1139,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
for bound in bounds {
let bound_span = self.tcx().associated_items(bound.def_id()).find(|item| {
item.kind == ty::AssociatedKind::Type &&
- self.tcx().hygienic_eq(assoc_name, item.ident, bound.def_id())
+ self.tcx().hygienic_eq(assoc_name, item.ident, bound.def_id())
})
.and_then(|item| self.tcx().hir.span_if_local(item.def_id));
if let Some(span) = bound_span {
err.span_label(span, format!("ambiguous `{}` from `{}`",
- assoc_name,
- bound));
+ assoc_name,
+ bound));
} else {
span_note!(&mut err, span,
"associated type `{}` could derive from `{}`",
@@ -1197,8 +1195,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
}
};
- let candidates =
- traits::supertraits(tcx, ty::Binder::bind(trait_ref))
+ let candidates = traits::supertraits(tcx, ty::Binder::bind(trait_ref))
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_name));
match self.one_bound_for_assoc_type(candidates, "Self", assoc_name, span) {
@@ -1229,7 +1226,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
let (assoc_ident, def_scope) = tcx.adjust_ident(assoc_name, trait_did, ref_id);
let item = tcx.associated_items(trait_did).find(|i| {
Namespace::from(i.kind) == Namespace::Type &&
- i.ident.modern() == assoc_ident
+ i.ident.modern() == assoc_ident
})
.expect("missing associated type");
@@ -1292,8 +1289,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
if err_for_lt { continue }
err_for_lt = true;
(struct_span_err!(self.tcx().sess, lt.span, E0110,
- "lifetime parameters are not allowed on \
- this type"),
+ "lifetime parameters are not allowed on this type"),
lt.span,
"lifetime")
}
@@ -1301,7 +1297,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
if err_for_ty { continue }
err_for_ty = true;
(struct_span_err!(self.tcx().sess, ty.span, E0109,
- "type parameters are not allowed on this type"),
+ "type parameters are not allowed on this type"),
ty.span,
"type")
}
@@ -1589,7 +1585,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
));
// Find any late-bound regions declared in return type that do
- // not appear in the arguments. These are not wellformed.
+ // not appear in the arguments. These are not well-formed.
//
// Example:
// for<'a> fn() -> &'a str <-- 'a is bad
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index 5967bd1ba3eea..d9dee917b01e4 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -75,7 +75,7 @@ impl<'a, 'tcx> CheckVisitor<'a, 'tcx> {
let msg = if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
format!("unused import: `{}`", snippet)
} else {
- "unused import".to_string()
+ "unused import".to_owned()
};
self.tcx.lint_node(lint::builtin::UNUSED_IMPORTS, id, span, &msg);
}
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index db08bf8095352..c54d9e4b47578 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -55,33 +55,29 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
}
fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) {
- match tcx.type_of(impl_did).sty {
- ty::Adt(..) => {}
- _ => {
- // Destructors only work on nominal types.
- if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_did) {
- match tcx.hir.find(impl_node_id) {
- Some(Node::Item(item)) => {
- let span = match item.node {
- ItemKind::Impl(.., ref ty, _) => ty.span,
- _ => item.span,
- };
- struct_span_err!(tcx.sess,
- span,
- E0120,
- "the Drop trait may only be implemented on \
- structures")
- .span_label(span, "implementing Drop requires a struct")
- .emit();
- }
- _ => {
- bug!("didn't find impl in ast map");
- }
- }
+ if let ty::Adt(..) = tcx.type_of(impl_did).sty {
+ /* do nothing */
+ } else {
+ // Destructors only work on nominal types.
+ if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_did) {
+ if let Some(Node::Item(item)) = tcx.hir.find(impl_node_id) {
+ let span = match item.node {
+ ItemKind::Impl(.., ref ty, _) => ty.span,
+ _ => item.span,
+ };
+ struct_span_err!(tcx.sess,
+ span,
+ E0120,
+ "the Drop trait may only be implemented on \
+ structures")
+ .span_label(span, "implementing Drop requires a struct")
+ .emit();
} else {
- bug!("found external impl of Drop trait on \
- something other than a struct");
+ bug!("didn't find impl in ast map");
}
+ } else {
+ bug!("found external impl of Drop trait on \
+ something other than a struct");
}
}
}
@@ -92,8 +88,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did:
let impl_node_id = if let Some(n) = tcx.hir.as_local_node_id(impl_did) {
n
} else {
- debug!("visit_implementation_of_copy(): impl not in this \
- crate");
+ debug!("visit_implementation_of_copy(): impl not in this crate");
return;
};
@@ -119,11 +114,11 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did:
};
let mut err = struct_span_err!(tcx.sess,
- span,
- E0204,
- "the trait `Copy` may not be implemented for this type");
+ span,
+ E0204,
+ "the trait `Copy` may not be implemented for this type");
for span in fields.iter().map(|f| tcx.def_span(f.did)) {
- err.span_label(span, "this field does not implement `Copy`");
+ err.span_label(span, "this field does not implement `Copy`");
}
err.emit()
}
@@ -173,12 +168,9 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did);
let coerce_unsized_trait = gcx.lang_items().coerce_unsized_trait().unwrap();
- let unsize_trait = match gcx.lang_items().require(UnsizeTraitLangItem) {
- Ok(id) => id,
- Err(err) => {
- gcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err));
- }
- };
+ let unsize_trait = gcx.lang_items().require(UnsizeTraitLangItem).unwrap_or_else(|err| {
+ gcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err));
+ });
// this provider should only get invoked for local def-ids
let impl_node_id = gcx.hir.as_local_node_id(impl_did).unwrap_or_else(|| {
@@ -210,9 +202,9 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
mk_ptr: &dyn Fn(Ty<'gcx>) -> Ty<'gcx>| {
if (mt_a.mutbl, mt_b.mutbl) == (hir::MutImmutable, hir::MutMutable) {
infcx.report_mismatched_types(&cause,
- mk_ptr(mt_b.ty),
- target,
- ty::error::TypeError::Mutability)
+ mk_ptr(mt_b.ty),
+ target,
+ ty::error::TypeError::Mutability)
.emit();
}
(mt_a.ty, mt_b.ty, unsize_trait, None)
@@ -235,7 +227,7 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
}
(&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) if def_a.is_struct() &&
- def_b.is_struct() => {
+ def_b.is_struct() => {
if def_a != def_b {
let source_path = gcx.item_path_str(def_a.did);
let target_path = gcx.item_path_str(def_b.did);
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index 52e37b8d0ce11..1955a709dbfe5 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -315,8 +315,7 @@ impl<'a, 'tcx> InherentCollect<'a, 'tcx> {
E0116,
"cannot define inherent `impl` for a type outside of the crate \
where the type is defined")
- .span_label(item.span,
- "impl for type defined outside of crate.")
+ .span_label(item.span, "impl for type defined outside of crate.")
.note("define and implement a trait or new type instead")
.emit();
}
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index ecb7a8ea8b62e..616ca97a7a75d 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -36,8 +36,8 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) {
debug!("(checking implementation) adding impl for trait '{:?}', item '{}'",
- trait_ref,
- tcx.item_path_str(impl_def_id));
+ trait_ref,
+ tcx.item_path_str(impl_def_id));
// Skip impls where one of the self type is an error type.
// This occurs with e.g. resolve failures (#30589).
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index f9b89488232d2..b155587dddc41 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -33,131 +33,126 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
/// reports.
fn visit_item(&mut self, item: &hir::Item) {
let def_id = self.tcx.hir.local_def_id(item.id);
- match item.node {
- hir::ItemKind::Impl(.., Some(_), _, _) => {
- // "Trait" impl
- debug!("coherence2::orphan check: trait impl {}",
- self.tcx.hir.node_to_string(item.id));
- let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
- let trait_def_id = trait_ref.def_id;
- let cm = self.tcx.sess.source_map();
- let sp = cm.def_span(item.span);
- match traits::orphan_check(self.tcx, def_id) {
- Ok(()) => {}
- Err(traits::OrphanCheckErr::NoLocalInputType) => {
- struct_span_err!(self.tcx.sess,
- sp,
- E0117,
- "only traits defined in the current crate can be \
- implemented for arbitrary types")
- .span_label(sp, "impl doesn't use types inside crate")
- .note("the impl does not reference any types defined in this crate")
- .note("define and implement a trait or new type instead")
- .emit();
- return;
- }
- Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
- struct_span_err!(self.tcx.sess,
- sp,
- E0210,
- "type parameter `{}` must be used as the type parameter \
- for some local type (e.g. `MyStruct<{}>`)",
- param_ty,
- param_ty)
- .span_label(sp,
- format!("type parameter `{}` must be used as the type \
- parameter for some local type", param_ty))
- .note("only traits defined in the current crate can be implemented \
- for a type parameter")
- .emit();
- return;
- }
+ // "Trait" impl
+ if let hir::ItemKind::Impl(.., Some(_), _, _) = item.node {
+ debug!("coherence2::orphan check: trait impl {}",
+ self.tcx.hir.node_to_string(item.id));
+ let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
+ let trait_def_id = trait_ref.def_id;
+ let cm = self.tcx.sess.source_map();
+ let sp = cm.def_span(item.span);
+ match traits::orphan_check(self.tcx, def_id) {
+ Ok(()) => {}
+ Err(traits::OrphanCheckErr::NoLocalInputType) => {
+ struct_span_err!(self.tcx.sess,
+ sp,
+ E0117,
+ "only traits defined in the current crate can be \
+ implemented for arbitrary types")
+ .span_label(sp, "impl doesn't use types inside crate")
+ .note("the impl does not reference any types defined in this crate")
+ .note("define and implement a trait or new type instead")
+ .emit();
+ return;
+ }
+ Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
+ struct_span_err!(self.tcx.sess,
+ sp,
+ E0210,
+ "type parameter `{}` must be used as the type parameter \
+ for some local type (e.g. `MyStruct<{}>`)",
+ param_ty,
+ param_ty)
+ .span_label(sp,
+ format!("type parameter `{}` must be used as the type \
+ parameter for some local type", param_ty))
+ .note("only traits defined in the current crate can be implemented \
+ for a type parameter")
+ .emit();
+ return;
}
+ }
- // In addition to the above rules, we restrict impls of auto traits
- // so that they can only be implemented on nominal types, such as structs,
- // enums or foreign types. To see why this restriction exists, consider the
- // following example (#22978). Imagine that crate A defines an auto trait
- // `Foo` and a fn that operates on pairs of types:
- //
- // ```
- // // Crate A
- // auto trait Foo { }
- // fn two_foos(..) {
- // one_foo::<(A,B)>(..)
- // }
- // fn one_foo(..) { .. }
- // ```
- //
- // This type-checks fine; in particular the fn
- // `two_foos` is able to conclude that `(A,B):Foo`
- // because `A:Foo` and `B:Foo`.
- //
- // Now imagine that crate B comes along and does the following:
- //
- // ```
- // struct A { }
- // struct B { }
- // impl Foo for A { }
- // impl Foo for B { }
- // impl !Send for (A, B) { }
- // ```
- //
- // This final impl is legal according to the orpan
- // rules, but it invalidates the reasoning from
- // `two_foos` above.
- debug!("trait_ref={:?} trait_def_id={:?} trait_is_auto={}",
- trait_ref,
- trait_def_id,
- self.tcx.trait_is_auto(trait_def_id));
- if self.tcx.trait_is_auto(trait_def_id) &&
- !trait_def_id.is_local() {
- let self_ty = trait_ref.self_ty();
- let opt_self_def_id = match self_ty.sty {
- ty::Adt(self_def, _) => Some(self_def.did),
- ty::Foreign(did) => Some(did),
- _ => None,
- };
+ // In addition to the above rules, we restrict impls of auto traits
+ // so that they can only be implemented on nominal types, such as structs,
+ // enums or foreign types. To see why this restriction exists, consider the
+ // following example (#22978). Imagine that crate A defines an auto trait
+ // `Foo` and a fn that operates on pairs of types:
+ //
+ // ```
+ // // Crate A
+ // auto trait Foo { }
+ // fn two_foos(..) {
+ // one_foo::<(A,B)>(..)
+ // }
+ // fn one_foo(..) { .. }
+ // ```
+ //
+ // This type-checks fine; in particular the fn
+ // `two_foos` is able to conclude that `(A,B):Foo`
+ // because `A:Foo` and `B:Foo`.
+ //
+ // Now imagine that crate B comes along and does the following:
+ //
+ // ```
+ // struct A { }
+ // struct B { }
+ // impl Foo for A { }
+ // impl Foo for B { }
+ // impl !Send for (A, B) { }
+ // ```
+ //
+ // This final impl is legal according to the orpan
+ // rules, but it invalidates the reasoning from
+ // `two_foos` above.
+ debug!("trait_ref={:?} trait_def_id={:?} trait_is_auto={}",
+ trait_ref,
+ trait_def_id,
+ self.tcx.trait_is_auto(trait_def_id));
+ if self.tcx.trait_is_auto(trait_def_id) &&
+ !trait_def_id.is_local() {
+ let self_ty = trait_ref.self_ty();
+ let opt_self_def_id = match self_ty.sty {
+ ty::Adt(self_def, _) => Some(self_def.did),
+ ty::Foreign(did) => Some(did),
+ _ => None,
+ };
- let msg = match opt_self_def_id {
- // We only want to permit nominal types, but not *all* nominal types.
- // They must be local to the current crate, so that people
- // can't do `unsafe impl Send for Rc` or
- // `impl !Send for Box`.
- Some(self_def_id) => {
- if self_def_id.is_local() {
- None
- } else {
- Some((
- format!("cross-crate traits with a default impl, like `{}`, \
- can only be implemented for a struct/enum type \
- defined in the current crate",
- self.tcx.item_path_str(trait_def_id)),
- "can't implement cross-crate trait for type in another crate"
- ))
- }
- }
- _ => {
- Some((format!("cross-crate traits with a default impl, like `{}`, can \
- only be implemented for a struct/enum type, not `{}`",
- self.tcx.item_path_str(trait_def_id),
- self_ty),
- "can't implement cross-crate trait with a default impl for \
- non-struct/enum type"))
+ let msg = match opt_self_def_id {
+ // We only want to permit nominal types, but not *all* nominal types.
+ // They must be local to the current crate, so that people
+ // can't do `unsafe impl Send for Rc` or
+ // `impl !Send for Box`.
+ Some(self_def_id) => {
+ if self_def_id.is_local() {
+ None
+ } else {
+ Some((
+ format!("cross-crate traits with a default impl, like `{}`, \
+ can only be implemented for a struct/enum type \
+ defined in the current crate",
+ self.tcx.item_path_str(trait_def_id)),
+ "can't implement cross-crate trait for type in another crate"
+ ))
}
- };
-
- if let Some((msg, label)) = msg {
- struct_span_err!(self.tcx.sess, sp, E0321, "{}", msg)
- .span_label(sp, label)
- .emit();
- return;
}
+ _ => {
+ Some((format!("cross-crate traits with a default impl, like `{}`, can \
+ only be implemented for a struct/enum type, not `{}`",
+ self.tcx.item_path_str(trait_def_id),
+ self_ty),
+ "can't implement cross-crate trait with a default impl for \
+ non-struct/enum type"))
+ }
+ };
+
+ if let Some((msg, label)) = msg {
+ struct_span_err!(self.tcx.sess, sp, E0321, "{}", msg)
+ .span_label(sp, label)
+ .emit();
+ return;
}
}
- _ => {
- // Not an impl
- }
}
}
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index 9e19854a571fc..bdbf93ddec286 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -29,52 +29,49 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
item: &'v hir::Item,
impl_generics: Option<&hir::Generics>,
unsafety: hir::Unsafety,
- polarity: hir::ImplPolarity) {
- match self.tcx.impl_trait_ref(self.tcx.hir.local_def_id(item.id)) {
- None => {}
-
- Some(trait_ref) => {
- let trait_def = self.tcx.trait_def(trait_ref.def_id);
- let unsafe_attr = impl_generics.and_then(|generics| {
- generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle")
- });
- match (trait_def.unsafety, unsafe_attr, unsafety, polarity) {
- (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => {
- span_err!(self.tcx.sess,
- item.span,
- E0199,
- "implementing the trait `{}` is not unsafe",
- trait_ref);
- }
+ polarity: hir::ImplPolarity)
+ {
+ if let Some(trait_ref) = self.tcx.impl_trait_ref(self.tcx.hir.local_def_id(item.id)) {
+ let trait_def = self.tcx.trait_def(trait_ref.def_id);
+ let unsafe_attr = impl_generics.and_then(|generics| {
+ generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle")
+ });
+ match (trait_def.unsafety, unsafe_attr, unsafety, polarity) {
+ (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => {
+ span_err!(self.tcx.sess,
+ item.span,
+ E0199,
+ "implementing the trait `{}` is not unsafe",
+ trait_ref);
+ }
- (Unsafety::Unsafe, _, Unsafety::Normal, hir::ImplPolarity::Positive) => {
- span_err!(self.tcx.sess,
- item.span,
- E0200,
- "the trait `{}` requires an `unsafe impl` declaration",
- trait_ref);
- }
+ (Unsafety::Unsafe, _, Unsafety::Normal, hir::ImplPolarity::Positive) => {
+ span_err!(self.tcx.sess,
+ item.span,
+ E0200,
+ "the trait `{}` requires an `unsafe impl` declaration",
+ trait_ref);
+ }
- (Unsafety::Normal, Some(attr_name), Unsafety::Normal,
- hir::ImplPolarity::Positive) =>
- {
- span_err!(self.tcx.sess,
- item.span,
- E0569,
- "requires an `unsafe impl` declaration due to `#[{}]` attribute",
- attr_name);
- }
+ (Unsafety::Normal, Some(attr_name), Unsafety::Normal,
+ hir::ImplPolarity::Positive) =>
+ {
+ span_err!(self.tcx.sess,
+ item.span,
+ E0569,
+ "requires an `unsafe impl` declaration due to `#[{}]` attribute",
+ attr_name);
+ }
- (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative) => {
- // Reported in AST validation
- self.tcx.sess.delay_span_bug(item.span, "unsafe negative impl");
- }
- (_, _, Unsafety::Normal, hir::ImplPolarity::Negative) |
- (Unsafety::Unsafe, _, Unsafety::Unsafe, hir::ImplPolarity::Positive) |
- (Unsafety::Normal, Some(_), Unsafety::Unsafe, hir::ImplPolarity::Positive) |
- (Unsafety::Normal, None, Unsafety::Normal, _) => {
- // OK
- }
+ (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative) => {
+ // Reported in AST validation
+ self.tcx.sess.delay_span_bug(item.span, "unsafe negative impl");
+ }
+ (_, _, Unsafety::Normal, hir::ImplPolarity::Negative) |
+ (Unsafety::Unsafe, _, Unsafety::Unsafe, hir::ImplPolarity::Positive) |
+ (Unsafety::Normal, Some(_), Unsafety::Unsafe, hir::ImplPolarity::Positive) |
+ (Unsafety::Normal, None, Unsafety::Normal, _) => {
+ // OK
}
}
}
@@ -83,11 +80,8 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for UnsafetyChecker<'cx, 'tcx> {
fn visit_item(&mut self, item: &'v hir::Item) {
- match item.node {
- hir::ItemKind::Impl(unsafety, polarity, _, ref generics, ..) => {
- self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
- }
- _ => {}
+ if let hir::ItemKind::Impl(unsafety, polarity, _, ref generics, ..) = item.node {
+ self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
}
}
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index bb5753f432a02..d3134b63bb661 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -56,14 +56,16 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc::hir::GenericParamKind;
use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
+use std::iter;
+
///////////////////////////////////////////////////////////////////////////
// Main entry point
pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut visitor = CollectItemTypesVisitor { tcx: tcx };
tcx.hir
- .krate()
- .visit_all_item_likes(&mut visitor.as_deep_visitor());
+ .krate()
+ .visit_all_item_likes(&mut visitor.as_deep_visitor());
}
pub fn provide(providers: &mut Providers) {
@@ -195,7 +197,8 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
E0121,
"the type placeholder `_` is not allowed within types on item signatures"
).span_label(span, "not allowed in type signatures")
- .emit();
+ .emit();
+
self.tcx().types.err
}
@@ -574,8 +577,8 @@ fn convert_variant<'a, 'tcx>(
"field `{}` is already declared",
f.ident
).span_label(f.span, "field already declared")
- .span_label(prev_span, format!("`{}` first declared here", f.ident))
- .emit();
+ .span_label(prev_span, format!("`{}` first declared here", f.ident))
+ .emit();
} else {
seen_fields.insert(f.ident.modern(), f.span);
}
@@ -819,14 +822,11 @@ fn has_late_bound_regions<'a, 'tcx>(
has_late_bound_regions: None,
};
for param in &generics.params {
- match param.kind {
- GenericParamKind::Lifetime { .. } => {
- let hir_id = tcx.hir.node_to_hir_id(param.id);
- if tcx.is_late_bound(hir_id) {
- return Some(param.span);
- }
+ if let GenericParamKind::Lifetime { .. } = param.kind {
+ let hir_id = tcx.hir.node_to_hir_id(param.id);
+ if tcx.is_late_bound(hir_id) {
+ return Some(param.span);
}
- _ => {}
}
}
visitor.visit_fn_decl(decl);
@@ -1309,6 +1309,7 @@ fn find_existential_constraints<'a, 'tcx>(
def_id: DefId,
found: Option<(Span, ty::Ty<'tcx>)>,
}
+
impl<'a, 'tcx> ConstraintLocator<'a, 'tcx> {
fn check(&mut self, def_id: DefId) {
trace!("checking {:?}", def_id);
@@ -1342,6 +1343,7 @@ fn find_existential_constraints<'a, 'tcx>(
}
}
}
+
impl<'a, 'tcx> intravisit::Visitor<'tcx> for ConstraintLocator<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
intravisit::NestedVisitorMap::All(&self.tcx.hir)
@@ -1368,6 +1370,7 @@ fn find_existential_constraints<'a, 'tcx>(
intravisit::walk_trait_item(self, it);
}
}
+
let mut locator = ConstraintLocator {
def_id,
tcx,
@@ -1375,7 +1378,9 @@ fn find_existential_constraints<'a, 'tcx>(
};
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
let parent = tcx.hir.get_parent(node_id);
+
trace!("parent_id: {:?}", parent);
+
if parent == ast::CRATE_NODE_ID {
intravisit::walk_crate(&mut locator, tcx.hir.krate());
} else {
@@ -1390,6 +1395,7 @@ fn find_existential_constraints<'a, 'tcx>(
),
}
}
+
match locator.found {
Some((_, ty)) => ty,
None => {
@@ -1780,17 +1786,14 @@ fn explicit_predicates_of<'a, 'tcx>(
// Collect the predicates that were written inline by the user on each
// type parameter (e.g., ``).
for param in &ast_generics.params {
- match param.kind {
- GenericParamKind::Type { .. } => {
- let name = param.name.ident().as_interned_str();
- let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
- index += 1;
-
- let sized = SizedByDefault::Yes;
- let bounds = compute_bounds(&icx, param_ty, ¶m.bounds, sized, param.span);
- predicates.extend(bounds.predicates(tcx, param_ty));
- }
- _ => {}
+ if let GenericParamKind::Type { .. } = param.kind {
+ let name = param.name.ident().as_interned_str();
+ let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
+ index += 1;
+
+ let sized = SizedByDefault::Yes;
+ let bounds = compute_bounds(&icx, param_ty, ¶m.bounds, sized, param.span);
+ predicates.extend(bounds.predicates(tcx, param_ty));
}
}
@@ -1828,8 +1831,9 @@ fn explicit_predicates_of<'a, 'tcx>(
&mut projections,
);
- predicates.push(trait_ref.to_predicate());
- predicates.extend(projections.iter().map(|p| p.to_predicate()));
+ predicates.extend(
+ iter::once(trait_ref.to_predicate()).chain(
+ projections.iter().map(|p| p.to_predicate())));
}
&hir::GenericBound::Outlives(ref lifetime) => {
@@ -1843,7 +1847,8 @@ fn explicit_predicates_of<'a, 'tcx>(
&hir::WherePredicate::RegionPredicate(ref region_pred) => {
let r1 = AstConv::ast_region_to_region(&icx, ®ion_pred.lifetime, None);
- for bound in ®ion_pred.bounds {
+
+ predicates.extend(region_pred.bounds.iter().map(|bound| {
let r2 = match bound {
hir::GenericBound::Outlives(lt) => {
AstConv::ast_region_to_region(&icx, lt, None)
@@ -1851,8 +1856,9 @@ fn explicit_predicates_of<'a, 'tcx>(
_ => bug!(),
};
let pred = ty::Binder::bind(ty::OutlivesPredicate(r1, r2));
- predicates.push(ty::Predicate::RegionOutlives(pred))
- }
+
+ ty::Predicate::RegionOutlives(pred)
+ }))
}
&hir::WherePredicate::EqPredicate(..) => {
@@ -1867,9 +1873,7 @@ fn explicit_predicates_of<'a, 'tcx>(
let trait_item = tcx.hir.trait_item(trait_item_ref.id);
let bounds = match trait_item.node {
hir::TraitItemKind::Type(ref bounds, _) => bounds,
- _ => {
- return vec![].into_iter();
- }
+ _ => return vec![].into_iter()
};
let assoc_ty =
@@ -1930,6 +1934,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
) -> Bounds<'tcx> {
let mut region_bounds = vec![];
let mut trait_bounds = vec![];
+
for ast_bound in ast_bounds {
match *ast_bound {
hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => trait_bounds.push(b),
@@ -2020,13 +2025,13 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
let check = |ast_ty: &hir::Ty, ty: Ty| {
if ty.is_simd() {
tcx.sess
- .struct_span_err(
- ast_ty.span,
- &format!(
- "use of SIMD type `{}` in FFI is highly experimental and \
- may result in invalid code",
- tcx.hir.node_to_pretty_string(ast_ty.id)
- ),
+ .struct_span_err(
+ ast_ty.span,
+ &format!(
+ "use of SIMD type `{}` in FFI is highly experimental and \
+ may result in invalid code",
+ tcx.hir.node_to_pretty_string(ast_ty.id)
+ ),
)
.help("add #![feature(simd_ffi)] to the crate attributes to enable")
.emit();
@@ -2089,7 +2094,7 @@ fn from_target_feature(
};
// We allow comma separation to enable multiple features
- for feature in value.as_str().split(',') {
+ target_features.extend(value.as_str().split(',').filter_map(|feature| {
// Only allow whitelisted features per platform
let feature_gate = match whitelist.get(feature) {
Some(g) => g,
@@ -2108,7 +2113,7 @@ fn from_target_feature(
}
}
err.emit();
- continue;
+ return None;
}
};
@@ -2135,10 +2140,11 @@ fn from_target_feature(
feature_gate::GateIssue::Language,
&format!("the target feature `{}` is currently unstable", feature),
);
- continue;
+ return None;
}
- target_features.push(Symbol::intern(feature));
- }
+
+ Some(Symbol::intern(feature))
+ }));
}
}
@@ -2171,7 +2177,7 @@ fn linkage_by_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, name: &
tcx.sess.span_fatal(span, "invalid linkage specified")
} else {
tcx.sess
- .fatal(&format!("invalid linkage specified: {}", name))
+ .fatal(&format!("invalid linkage specified: {}", name))
}
}
}
@@ -2269,7 +2275,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
E0558,
"`export_name` attribute has invalid format"
).span_label(attr.span, "did you mean #[export_name=\"*\"]?")
- .emit();
+ .emit();
}
} else if attr.check_name("target_feature") {
if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs
index 1b481fc5a7d31..2fe9088b901c1 100644
--- a/src/librustc_typeck/constrained_type_params.rs
+++ b/src/librustc_typeck/constrained_type_params.rs
@@ -76,11 +76,8 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
- match *r {
- ty::ReEarlyBound(data) => {
- self.parameters.push(Parameter::from(data));
- }
- _ => {}
+ if let ty::ReEarlyBound(data) = *r {
+ self.parameters.push(Parameter::from(data));
}
false
}
@@ -203,6 +200,6 @@ pub fn setup_constraining_predicates<'tcx>(tcx: TyCtxt,
}
debug!("setup_constraining_predicates: predicates={:?} \
i={} impl_trait_ref={:?} input_parameters={:?}",
- predicates, i, impl_trait_ref, input_parameters);
+ predicates, i, impl_trait_ref, input_parameters);
}
}
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index 11260b8f11e12..f2b1ad58677fc 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -71,15 +71,12 @@ struct ImplWfCheck<'a, 'tcx: 'a> {
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item) {
- match item.node {
- hir::ItemKind::Impl(.., ref impl_item_refs) => {
- let impl_def_id = self.tcx.hir.local_def_id(item.id);
- enforce_impl_params_are_constrained(self.tcx,
- impl_def_id,
- impl_item_refs);
- enforce_impl_items_are_distinct(self.tcx, impl_item_refs);
- }
- _ => { }
+ if let hir::ItemKind::Impl(.., ref impl_item_refs) = item.node {
+ let impl_def_id = self.tcx.hir.local_def_id(item.id);
+ enforce_impl_params_are_constrained(self.tcx,
+ impl_def_id,
+ impl_item_refs);
+ enforce_impl_items_are_distinct(self.tcx, impl_item_refs);
}
}
@@ -182,7 +179,7 @@ fn enforce_impl_items_are_distinct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let impl_item = tcx.hir.impl_item(impl_item_ref.id);
let seen_items = match impl_item.node {
hir::ImplItemKind::Type(_) => &mut seen_type_items,
- _ => &mut seen_value_items,
+ _ => &mut seen_value_items,
};
match seen_items.entry(impl_item.ident.modern()) {
Occupied(entry) => {
@@ -191,7 +188,7 @@ fn enforce_impl_items_are_distinct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_item.ident);
err.span_label(*entry.get(),
format!("previous definition of `{}` here",
- impl_item.ident));
+ impl_item.ident));
err.span_label(impl_item.span, "duplicate definition");
err.emit();
}
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index c9aa0339dd469..3ca93f2dbe185 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -146,7 +146,7 @@ fn require_c_abi_if_variadic(tcx: TyCtxt,
span: Span) {
if decl.variadic && !(abi == Abi::C || abi == Abi::Cdecl) {
let mut err = struct_span_err!(tcx.sess, span, E0045,
- "variadic function must have C or cdecl calling convention");
+ "variadic function must have C or cdecl calling convention");
err.span_label(span, "variadics require C or cdecl calling convention").emit();
}
}
@@ -186,35 +186,29 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let main_t = tcx.type_of(main_def_id);
match main_t.sty {
ty::FnDef(..) => {
- match tcx.hir.find(main_id) {
- Some(Node::Item(it)) => {
- match it.node {
- hir::ItemKind::Fn(.., ref generics, _) => {
- let mut error = false;
- if !generics.params.is_empty() {
- let msg = "`main` function is not allowed to have generic \
- parameters".to_string();
- let label = "`main` cannot have generic parameters".to_string();
- struct_span_err!(tcx.sess, generics.span, E0131, "{}", msg)
- .span_label(generics.span, label)
- .emit();
- error = true;
- }
- if let Some(sp) = generics.where_clause.span() {
- struct_span_err!(tcx.sess, sp, E0646,
- "`main` function is not allowed to have a `where` clause")
- .span_label(sp, "`main` cannot have a `where` clause")
- .emit();
- error = true;
- }
- if error {
- return;
- }
- }
- _ => ()
+ if let Some(Node::Item(it)) = tcx.hir.find(main_id) {
+ if let hir::ItemKind::Fn(.., ref generics, _) = it.node {
+ let mut error = false;
+ if !generics.params.is_empty() {
+ let msg = "`main` function is not allowed to have generic \
+ parameters".to_owned();
+ let label = "`main` cannot have generic parameters".to_string();
+ struct_span_err!(tcx.sess, generics.span, E0131, "{}", msg)
+ .span_label(generics.span, label)
+ .emit();
+ error = true;
+ }
+ if let Some(sp) = generics.where_clause.span() {
+ struct_span_err!(tcx.sess, sp, E0646,
+ "`main` function is not allowed to have a `where` clause")
+ .span_label(sp, "`main` cannot have a `where` clause")
+ .emit();
+ error = true;
+ }
+ if error {
+ return;
}
}
- _ => ()
}
let actual = tcx.fn_sig(main_def_id);
@@ -258,34 +252,28 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let start_t = tcx.type_of(start_def_id);
match start_t.sty {
ty::FnDef(..) => {
- match tcx.hir.find(start_id) {
- Some(Node::Item(it)) => {
- match it.node {
- hir::ItemKind::Fn(.., ref generics, _) => {
- let mut error = false;
- if !generics.params.is_empty() {
- struct_span_err!(tcx.sess, generics.span, E0132,
- "start function is not allowed to have type parameters")
- .span_label(generics.span,
- "start function cannot have type parameters")
- .emit();
- error = true;
- }
- if let Some(sp) = generics.where_clause.span() {
- struct_span_err!(tcx.sess, sp, E0647,
- "start function is not allowed to have a `where` clause")
- .span_label(sp, "start function cannot have a `where` clause")
- .emit();
- error = true;
- }
- if error {
- return;
- }
- }
- _ => ()
+ if let Some(Node::Item(it)) = tcx.hir.find(start_id) {
+ if let hir::ItemKind::Fn(.., ref generics, _) = it.node {
+ let mut error = false;
+ if !generics.params.is_empty() {
+ struct_span_err!(tcx.sess, generics.span, E0132,
+ "start function is not allowed to have type parameters")
+ .span_label(generics.span,
+ "start function cannot have type parameters")
+ .emit();
+ error = true;
+ }
+ if let Some(sp) = generics.where_clause.span() {
+ struct_span_err!(tcx.sess, sp, E0647,
+ "start function is not allowed to have a `where` clause")
+ .span_label(sp, "start function cannot have a `where` clause")
+ .emit();
+ error = true;
+ }
+ if error {
+ return;
}
}
- _ => ()
}
let se_ty = tcx.mk_fn_ptr(ty::Binder::bind(
@@ -388,6 +376,7 @@ pub fn hir_ty_to_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_ty: &hir::Ty) ->
let env_node_id = tcx.hir.get_parent(hir_ty.id);
let env_def_id = tcx.hir.local_def_id(env_node_id);
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id);
+
astconv::AstConv::ast_ty_to_ty(&item_cx, hir_ty)
}
@@ -403,6 +392,7 @@ pub fn hir_trait_to_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_trait:
let principal = astconv::AstConv::instantiate_poly_trait_ref_inner(
&item_cx, hir_trait, tcx.types.err, &mut projections, true
);
+
(principal, projections)
}
diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs
index 63a424936eb4c..cca77b20d9b30 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/src/librustc_typeck/outlives/mod.rs
@@ -55,9 +55,7 @@ fn inferred_outlives_of<'a, 'tcx>(
.iter()
.map(|out_pred| match out_pred {
ty::Predicate::RegionOutlives(p) => p.to_string(),
-
ty::Predicate::TypeOutlives(p) => p.to_string(),
-
err => bug!("unexpected predicate {:?}", err),
}).collect();
pred.sort();
diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs
index c3c2ae667ddd9..48c495e1c9317 100644
--- a/src/librustc_typeck/outlives/test.rs
+++ b/src/librustc_typeck/outlives/test.rs
@@ -14,8 +14,8 @@ use rustc::ty::TyCtxt;
pub fn test_inferred_outlives<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
tcx.hir
- .krate()
- .visit_all_item_likes(&mut OutlivesTest { tcx });
+ .krate()
+ .visit_all_item_likes(&mut OutlivesTest { tcx });
}
struct OutlivesTest<'a, 'tcx: 'a> {
diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs
index 0d833c50d7e3b..6bf7a3501bed9 100644
--- a/src/librustc_typeck/outlives/utils.rs
+++ b/src/librustc_typeck/outlives/utils.rs
@@ -148,15 +148,9 @@ fn is_free_region<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, region: Region<'_>) -> bool
// field: &'static T, // this would generate a ReStatic
// }
RegionKind::ReStatic => {
- if tcx
- .sess
- .features_untracked()
- .infer_static_outlives_requirements
- {
- true
- } else {
- false
- }
+ tcx.sess
+ .features_untracked()
+ .infer_static_outlives_requirements
}
// Late-bound regions can appear in `fn` types:
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index aaa0fd8e099ef..25f6b259e96bc 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -55,7 +55,7 @@ fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
}
fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
- -> Lrc> {
+ -> Lrc> {
let id = tcx.hir.as_local_node_id(item_def_id).expect("expected local def-id");
let unsupported = || {
// Variance not relevant.
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 3d9f4a92f818a..a9ce236557779 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -90,6 +90,7 @@ impl<'a> StripUnconfigured<'a> {
parser.expect(&token::Comma)?;
let lo = parser.span.lo();
let (path, tokens) = parser.parse_meta_item_unrestricted()?;
+ parser.eat(&token::Comma); // Optional trailing comma
parser.expect(&token::CloseDelim(token::Paren))?;
Ok((cfg, path, tokens, parser.prev_span.with_lo(lo)))
}) {
diff --git a/src/test/ui/cfg-attr-trailing-comma.rs b/src/test/ui/cfg-attr-trailing-comma.rs
new file mode 100644
index 0000000000000..21e00544ca00b
--- /dev/null
+++ b/src/test/ui/cfg-attr-trailing-comma.rs
@@ -0,0 +1,13 @@
+// compile-flags: --cfg TRUE
+
+#[cfg_attr(TRUE, inline,)] // OK
+fn f() {}
+
+#[cfg_attr(FALSE, inline,)] // OK
+fn g() {}
+
+#[cfg_attr(TRUE, inline,,)] //~ ERROR expected `)`, found `,`
+fn h() {}
+
+#[cfg_attr(FALSE, inline,,)] //~ ERROR expected `)`, found `,`
+fn i() {}
diff --git a/src/test/ui/cfg-attr-trailing-comma.stderr b/src/test/ui/cfg-attr-trailing-comma.stderr
new file mode 100644
index 0000000000000..76a470417e9ed
--- /dev/null
+++ b/src/test/ui/cfg-attr-trailing-comma.stderr
@@ -0,0 +1,14 @@
+error: expected `)`, found `,`
+ --> $DIR/cfg-attr-trailing-comma.rs:9:25
+ |
+LL | #[cfg_attr(TRUE, inline,,)] //~ ERROR expected `)`, found `,`
+ | ^ expected `)`
+
+error: expected `)`, found `,`
+ --> $DIR/cfg-attr-trailing-comma.rs:12:26
+ |
+LL | #[cfg_attr(FALSE, inline,,)] //~ ERROR expected `)`, found `,`
+ | ^ expected `)`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 401dec7b184b1..f1a275b05c91b 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -224,6 +224,19 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
pub fn compute_stamp_hash(config: &Config) -> String {
let mut hash = DefaultHasher::new();
config.stage_id.hash(&mut hash);
+ match config.mode {
+ DebugInfoGdb => match config.gdb {
+ None => env::var_os("PATH").hash(&mut hash),
+ Some(ref s) if s.is_empty() => env::var_os("PATH").hash(&mut hash),
+ Some(ref s) => s.hash(&mut hash),
+ },
+ DebugInfoLldb => {
+ env::var_os("PATH").hash(&mut hash);
+ env::var_os("PYTHONPATH").hash(&mut hash);
+ },
+
+ _ => {},
+ };
format!("{:x}", hash.finish())
}