From 86b10671dbb7edf4090cb04476b4da205fd892b2 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Sun, 23 Apr 2017 22:00:09 -0700 Subject: [PATCH 1/5] Associated consts are not object safe. --- src/librustc/traits/object_safety.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index d190635bec306..f51711d031036 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -37,6 +37,9 @@ pub enum ObjectSafetyViolation { /// Method has something illegal Method(ast::Name, MethodViolationCode), + + /// Associated const + AssociatedConst(ast::Name), } impl ObjectSafetyViolation { @@ -54,6 +57,8 @@ impl ObjectSafetyViolation { in its arguments or return type", name).into(), ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) => format!("method `{}` has generic type parameters", name).into(), + ObjectSafetyViolation::AssociatedConst(name) => + format!("the trait cannot contain associated consts, such as `{}`", name), } } } @@ -141,6 +146,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { violations.push(ObjectSafetyViolation::SupertraitSelf); } + violations.extend(self.associated_items(trait_def_id) + .filter(|item| item.kind == ty::AssociatedKind::Const) + .map(|item| ObjectSafetyViolation::AssociatedConst(item.name))); + debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}", trait_def_id, violations); From bd31498ef668ee6c6ac0d2777ed5195b5f5d77e4 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Mon, 24 Apr 2017 01:19:12 -0700 Subject: [PATCH 2/5] Add compile-fail test. --- src/librustc/traits/object_safety.rs | 2 +- .../object-safety-associated-consts.rs | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/object-safety-associated-consts.rs diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index f51711d031036..90260d1737254 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -58,7 +58,7 @@ impl ObjectSafetyViolation { ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) => format!("method `{}` has generic type parameters", name).into(), ObjectSafetyViolation::AssociatedConst(name) => - format!("the trait cannot contain associated consts, such as `{}`", name), + format!("the trait cannot contain associated consts like `{}`", name), } } } diff --git a/src/test/compile-fail/object-safety-associated-consts.rs b/src/test/compile-fail/object-safety-associated-consts.rs new file mode 100644 index 0000000000000..e38187fe86ab3 --- /dev/null +++ b/src/test/compile-fail/object-safety-associated-consts.rs @@ -0,0 +1,26 @@ +// Copyright 2014 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. + +// Check that we correctly prevent users from making trait objects +// from traits with associated consts. + +trait Bar { + const X: usize; +} + +fn make_bar(t: &T) -> &Bar { + //~^ ERROR E0038 + //~| NOTE the trait cannot contain associated consts like `X` + //~| NOTE the trait `Bar` cannot be made into an object + t +} + +fn main() { +} From ed5d09d8f3e65d679aa24c6a50874920be5979f5 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Mon, 24 Apr 2017 01:20:36 -0700 Subject: [PATCH 3/5] Fix type error. --- src/librustc/traits/object_safety.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 90260d1737254..e53932888022b 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -58,7 +58,7 @@ impl ObjectSafetyViolation { ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) => format!("method `{}` has generic type parameters", name).into(), ObjectSafetyViolation::AssociatedConst(name) => - format!("the trait cannot contain associated consts like `{}`", name), + format!("the trait cannot contain associated consts like `{}`", name).into(), } } } From 95ffda1e9ee72f2170d55e4790bef21fb4ac11b1 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Mon, 24 Apr 2017 01:40:17 -0700 Subject: [PATCH 4/5] Style. --- src/test/compile-fail/object-safety-associated-consts.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/compile-fail/object-safety-associated-consts.rs b/src/test/compile-fail/object-safety-associated-consts.rs index e38187fe86ab3..499f41846f5a7 100644 --- a/src/test/compile-fail/object-safety-associated-consts.rs +++ b/src/test/compile-fail/object-safety-associated-consts.rs @@ -16,9 +16,9 @@ trait Bar { } fn make_bar(t: &T) -> &Bar { - //~^ ERROR E0038 - //~| NOTE the trait cannot contain associated consts like `X` - //~| NOTE the trait `Bar` cannot be made into an object + //~^ ERROR E0038 + //~| NOTE the trait cannot contain associated consts like `X` + //~| NOTE the trait `Bar` cannot be made into an object t } From 5dc43d272dcc1c7ba256f2d9cb88454c1770e053 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Mon, 24 Apr 2017 02:42:36 -0700 Subject: [PATCH 5/5] Feature gate in test. --- src/test/compile-fail/object-safety-associated-consts.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/compile-fail/object-safety-associated-consts.rs b/src/test/compile-fail/object-safety-associated-consts.rs index 499f41846f5a7..c442cd4083657 100644 --- a/src/test/compile-fail/object-safety-associated-consts.rs +++ b/src/test/compile-fail/object-safety-associated-consts.rs @@ -11,6 +11,8 @@ // Check that we correctly prevent users from making trait objects // from traits with associated consts. +#![feature(associated_consts)] + trait Bar { const X: usize; }