diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index de9c8a2feafb8..f87f5e6c2e6b7 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -1591,10 +1591,10 @@ impl BTreeMap { #[unstable(feature = "btree_range", reason = "matches collection reform specification, waiting for dust to settle", issue = "27787")] - pub fn range(&self, - min: Bound<&Min>, - max: Bound<&Max>) - -> Range + pub fn range(&self, + min: Bound<&Min>, + max: Bound<&Max>) + -> Range where K: Borrow + Borrow { range_impl!(&self.root, @@ -1633,10 +1633,10 @@ impl BTreeMap { #[unstable(feature = "btree_range", reason = "matches collection reform specification, waiting for dust to settle", issue = "27787")] - pub fn range_mut(&mut self, - min: Bound<&Min>, - max: Bound<&Max>) - -> RangeMut + pub fn range_mut(&mut self, + min: Bound<&Min>, + max: Bound<&Max>) + -> RangeMut where K: Borrow + Borrow { range_impl!(&mut self.root, diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 12d3465e5188d..55e9e3a1c34bb 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -154,10 +154,10 @@ impl BTreeSet { #[unstable(feature = "btree_range", reason = "matches collection reform specification, waiting for dust to settle", issue = "27787")] - pub fn range<'a, Min: ?Sized + Ord = T, Max: ?Sized + Ord = T>(&'a self, - min: Bound<&Min>, - max: Bound<&Max>) - -> Range<'a, T> + pub fn range<'a, Min: ?Sized + Ord, Max: ?Sized + Ord>(&'a self, + min: Bound<&Min>, + max: Bound<&Max>) + -> Range<'a, T> where T: Borrow + Borrow { fn first((a, _): (A, B)) -> A { diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 6f052f964c675..a30e5b1372af9 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2132,7 +2132,7 @@ pub trait Iterator { /// ``` #[unstable(feature = "iter_arith", reason = "bounds recently changed", issue = "27739")] - fn sum::Item>(self) -> S where + fn sum(self) -> S where S: Add + Zero, Self: Sized, { @@ -2157,7 +2157,7 @@ pub trait Iterator { /// ``` #[unstable(feature="iter_arith", reason = "bounds recently changed", issue = "27739")] - fn product::Item>(self) -> P where + fn product

(self) -> P where P: Mul + One, Self: Sized, { diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 2c5c664566a38..aff925d108272 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -16,6 +16,9 @@ use lint::{LintPass, LateLintPass, LintArray}; +// name of the future-incompatible group +pub const FUTURE_INCOMPATIBLE: &'static str = "future_incompatible"; + declare_lint! { pub CONST_ERR, Warn, @@ -124,6 +127,12 @@ declare_lint! { "detect private items in public interfaces not caught by the old implementation" } +declare_lint! { + pub INVALID_TYPE_PARAM_DEFAULT, + Warn, + "type parameter default erroneously allowed in invalid location" +} + /// Does nothing as a lint pass, but registers some `Lint`s /// which are used by other parts of the compiler. #[derive(Copy, Clone)] @@ -149,6 +158,7 @@ impl LintPass for HardwiredLints { TRIVIAL_CASTS, TRIVIAL_NUMERIC_CASTS, PRIVATE_IN_PUBLIC, + INVALID_TYPE_PARAM_DEFAULT, CONST_ERR ) } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 464f29a33937f..a4af12bcc7c9d 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -364,14 +364,16 @@ pub fn gather_attrs(attrs: &[ast::Attribute]) /// lints elsewhere in the compiler should call /// `Session::add_lint()` instead. pub fn raw_emit_lint(sess: &Session, + lints: &LintStore, lint: &'static Lint, lvlsrc: LevelSource, span: Option, msg: &str) { - raw_struct_lint(sess, lint, lvlsrc, span, msg).emit(); + raw_struct_lint(sess, lints, lint, lvlsrc, span, msg).emit(); } pub fn raw_struct_lint<'a>(sess: &'a Session, + lints: &LintStore, lint: &'static Lint, lvlsrc: LevelSource, span: Option, @@ -413,6 +415,18 @@ pub fn raw_struct_lint<'a>(sess: &'a Session, _ => sess.bug("impossible level in raw_emit_lint"), }; + // Check for future incompatibility lints and issue a stronger warning. + let future_incompat_lints = &lints.lint_groups[builtin::FUTURE_INCOMPATIBLE]; + let this_id = LintId::of(lint); + if future_incompat_lints.0.iter().any(|&id| id == this_id) { + let msg = "this lint will become a HARD ERROR in a future release!"; + if let Some(sp) = span { + err.span_note(sp, msg); + } else { + err.note(msg); + } + } + if let Some(span) = def { err.span_note(span, "lint level defined here"); } @@ -450,7 +464,7 @@ pub trait LintContext: Sized { Some(pair) => pair, }; - raw_emit_lint(&self.sess(), lint, (level, src), span, msg); + raw_emit_lint(&self.sess(), self.lints(), lint, (level, src), span, msg); } fn lookup(&self, @@ -463,7 +477,7 @@ pub trait LintContext: Sized { Some(pair) => pair, }; - raw_struct_lint(&self.sess(), lint, (level, src), span, msg) + raw_struct_lint(&self.sess(), self.lints(), lint, (level, src), span, msg) } /// Emit a lint at the appropriate level, for a particular span. diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 80ef334fe189b..f2e75960406f1 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -143,8 +143,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_MUT, UNREACHABLE_CODE, UNUSED_MUST_USE, UNUSED_UNSAFE, PATH_STATEMENTS, UNUSED_ATTRIBUTES); - add_lint_group!(sess, "future_incompatible", - PRIVATE_IN_PUBLIC); + add_lint_group!(sess, FUTURE_INCOMPATIBLE, + PRIVATE_IN_PUBLIC, INVALID_TYPE_PARAM_DEFAULT); // We have one lint pass defined specially store.register_late_pass(sess, false, box lint::GatherNodeLevels); diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 4197f80cb5ea3..67f26595a369f 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -2208,6 +2208,7 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &hir::EnumDef, sp: Span, // Use lint::raw_emit_lint rather than sess.add_lint because the lint-printing // pass for the latter already ran. lint::raw_struct_lint(&ccx.tcx().sess, + &ccx.tcx().sess.lint_store.borrow(), lint::builtin::VARIANT_SIZE_DIFFERENCES, *lvlsrc.unwrap(), Some(sp), diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index eaaa2c773791e..a03caba2a676e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -65,6 +65,7 @@ There are some shortcomings in this design: */ use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region}; +use lint; use middle::def; use middle::def_id::DefId; use constrained_type_params as ctp; @@ -1933,6 +1934,17 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let parent = tcx.map.get_parent(param.id); + if space != TypeSpace && default.is_some() { + if !tcx.sess.features.borrow().default_type_parameter_fallback { + tcx.sess.add_lint( + lint::builtin::INVALID_TYPE_PARAM_DEFAULT, + param.id, + param.span, + format!("defaults for type parameters are only allowed \ + on `struct` or `enum` definitions (see issue #27336)")); + } + } + let def = ty::TypeParameterDef { space: space, index: index, diff --git a/src/test/auxiliary/default_ty_param_cross_crate_crate.rs b/src/test/auxiliary/default_ty_param_cross_crate_crate.rs index 270cfdcb7f651..4bd8ecacb96b3 100644 --- a/src/test/auxiliary/default_ty_param_cross_crate_crate.rs +++ b/src/test/auxiliary/default_ty_param_cross_crate_crate.rs @@ -10,6 +10,7 @@ #![crate_type = "lib"] #![crate_name = "default_param_test"] +#![feature(default_type_parameter_fallback)] use std::marker::PhantomData; diff --git a/src/test/compile-fail/issue-26812.rs b/src/test/compile-fail/issue-26812.rs index c1ccfe269cdd3..060a66846d36f 100644 --- a/src/test/compile-fail/issue-26812.rs +++ b/src/test/compile-fail/issue-26812.rs @@ -8,5 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(default_type_parameter_fallback)] + fn avg(_: T) {} //~ ERROR associated type `Item` not found for `T` fn main() {} diff --git a/src/test/compile-fail/type-parameter-invalid-lint.rs b/src/test/compile-fail/type-parameter-invalid-lint.rs new file mode 100644 index 0000000000000..a3ecbfa84f0a8 --- /dev/null +++ b/src/test/compile-fail/type-parameter-invalid-lint.rs @@ -0,0 +1,17 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(future_incompatible)] +#![allow(dead_code)] + +fn avg(_: T) {} +//~^ ERROR defaults for type parameters are only allowed +//~| NOTE HARD ERROR +fn main() {}