diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 22854382df15c..ca17dccaac3d7 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -149,6 +149,12 @@ declare_lint! { "safe access to extern statics was erroneously allowed" } +declare_lint! { + pub TYPE_VS_VARIANT_AMBIGUITY, + Forbid, + "type vs variant ambiguity" +} + declare_lint! { pub SAFE_PACKED_BORROWS, Warn, @@ -400,6 +406,7 @@ impl LintPass for HardwiredLints { CONST_ERR, RENAMED_AND_REMOVED_LINTS, SAFE_EXTERN_STATICS, + TYPE_VS_VARIANT_AMBIGUITY, SAFE_PACKED_BORROWS, PATTERNS_IN_FNS_WITHOUT_BODY, LEGACY_DIRECTORY_OWNERSHIP, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 3aaa743b7e477..1e1b430ed9f7b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1288,7 +1288,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { span: Span, ty: Ty<'tcx>, ty_path_def: Def, - item_segment: &hir::PathSegment) + item_segment: &hir::PathSegment, + permit_variants: bool) -> (Ty<'tcx>, Def) { let tcx = self.tcx(); @@ -1305,11 +1306,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did) }); if let Some(variant_def) = variant_def { - check_type_alias_enum_variants_enabled(tcx, span); + if permit_variants { + check_type_alias_enum_variants_enabled(tcx, span); - let def = Def::Variant(variant_def.did); - tcx.check_stability(def.def_id(), Some(ref_id), span); - return (ty, def); + let def = Def::Variant(variant_def.did); + tcx.check_stability(def.def_id(), Some(ref_id), span); + return (ty, def); + } else { + use rustc::lint::builtin::TYPE_VS_VARIANT_AMBIGUITY; + tcx.lint_node( + TYPE_VS_VARIANT_AMBIGUITY, + ref_id, + span, + "type vs variant ambiguity", + ); + } } }, _ => (), @@ -1773,7 +1784,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } else { Def::Err }; - self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0 + self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment, false).0 } hir::TyKind::Array(ref ty, ref length) => { let length_def_id = tcx.hir().local_def_id(length.id); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1a5d164873d32..86ff5b1ea72b9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4623,7 +4623,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Def::Err }; let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span, - ty, def, segment); + ty, def, segment, true); // Write back the new resolution. let hir_id = self.tcx.hir().node_to_hir_id(node_id); diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index c55a1258ce955..2e5d18b19c600 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -111,7 +111,7 @@ use rustc::infer::InferOk; use rustc::lint; use rustc::middle; use rustc::session; -use rustc::session::config::nightly_options; +// use rustc::session::config::nightly_options; use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt}; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; @@ -130,20 +130,20 @@ pub struct TypeAndSubsts<'tcx> { ty: Ty<'tcx>, } -fn check_type_alias_enum_variants_enabled<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - span: Span) { - if !tcx.features().type_alias_enum_variants { - let mut err = tcx.sess.struct_span_err( - span, - "enum variants on type aliases are experimental" - ); - if nightly_options::is_nightly_build() { - help!(&mut err, - "add `#![feature(type_alias_enum_variants)]` to the \ - crate attributes to enable"); - } - err.emit(); - } +fn check_type_alias_enum_variants_enabled<'a, 'gcx, 'tcx>(_tcx: TyCtxt<'a, 'gcx, 'tcx>, + _span: Span) { + // if !tcx.features().type_alias_enum_variants { + // let mut err = tcx.sess.struct_span_err( + // span, + // "enum variants on type aliases are experimental" + // ); + // if nightly_options::is_nightly_build() { + // help!(&mut err, + // "add `#![feature(type_alias_enum_variants)]` to the \ + // crate attributes to enable"); + // } + // err.emit(); + // } } fn require_c_abi_if_variadic(tcx: TyCtxt, diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs index 8997c1824ca6d..7dfbb4cb37093 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs +++ b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-pass + enum Foo { Bar(i32), Baz { i: i32 }, diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr deleted file mode 100644 index cba643e18ca1a..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr +++ /dev/null @@ -1,34 +0,0 @@ -error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:19:13 - | -LL | let t = Alias::Bar(0); - | ^^^^^^^^^^ - | - = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable - -error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:21:13 - | -LL | let t = Alias::Baz { i: 0 }; - | ^^^^^^^^^^ - | - = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable - -error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:24:9 - | -LL | Alias::Bar(_i) => {} - | ^^^^^^^^^^^^^^ - | - = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable - -error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:26:9 - | -LL | Alias::Baz { i: _i } => {} - | ^^^^^^^^^^ - | - = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable - -error: aborting due to 4 previous errors - diff --git a/src/test/ui/type-alias-enum-variants-priority-2.rs b/src/test/ui/type-alias-enum-variants-priority-2.rs new file mode 100644 index 0000000000000..295f8acf62f85 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority-2.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_enum_variants)] + +enum E { + V(u8) +} + +impl E { + fn V() {} +} + +fn main() { + ::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied +} diff --git a/src/test/ui/type-alias-enum-variants-priority-2.stderr b/src/test/ui/type-alias-enum-variants-priority-2.stderr new file mode 100644 index 0000000000000..c6ec96ebb7d3b --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority-2.stderr @@ -0,0 +1,12 @@ +error[E0061]: this function takes 1 parameter but 0 parameters were supplied + --> $DIR/type-alias-enum-variants-priority-2.rs:12:5 + | +LL | V(u8) + | ----- defined here +... +LL | ::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied + | ^^^^^^^^ expected 1 parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/type-alias-enum-variants-priority.rs b/src/test/ui/type-alias-enum-variants-priority.rs new file mode 100644 index 0000000000000..e93c79a5366d1 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_enum_variants)] + +enum E { + V(u8) +} + +trait Tr { + type V; + fn f() -> Self::V; +} + +impl Tr for E { + type V = u8; + fn f() -> Self::V { loop {} } //~ ERROR type vs variant ambiguity +} + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants-priority.stderr b/src/test/ui/type-alias-enum-variants-priority.stderr new file mode 100644 index 0000000000000..0222ff63fbda3 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority.stderr @@ -0,0 +1,10 @@ +error: type vs variant ambiguity + --> $DIR/type-alias-enum-variants-priority.rs:14:15 + | +LL | fn f() -> Self::V { loop {} } //~ ERROR type vs variant ambiguity + | ^^^^^^^ + | + = note: #[forbid(type_vs_variant_ambiguity)] on by default + +error: aborting due to previous error +