Skip to content

Commit dcaebe0

Browse files
committed
[WIP] High priority resolutions for associated variants
1 parent 797eff9 commit dcaebe0

10 files changed

+94
-56
lines changed

src/librustc/lint/builtin.rs

+7
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ declare_lint! {
149149
"safe access to extern statics was erroneously allowed"
150150
}
151151

152+
declare_lint! {
153+
pub TYPE_VS_VARIANT_AMBIGUITY,
154+
Forbid,
155+
"type vs variant ambiguity"
156+
}
157+
152158
declare_lint! {
153159
pub SAFE_PACKED_BORROWS,
154160
Warn,
@@ -400,6 +406,7 @@ impl LintPass for HardwiredLints {
400406
CONST_ERR,
401407
RENAMED_AND_REMOVED_LINTS,
402408
SAFE_EXTERN_STATICS,
409+
TYPE_VS_VARIANT_AMBIGUITY,
403410
SAFE_PACKED_BORROWS,
404411
PATTERNS_IN_FNS_WITHOUT_BODY,
405412
LEGACY_DIRECTORY_OWNERSHIP,

src/librustc_typeck/astconv.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
12881288
span: Span,
12891289
ty: Ty<'tcx>,
12901290
ty_path_def: Def,
1291-
item_segment: &hir::PathSegment)
1291+
item_segment: &hir::PathSegment,
1292+
permit_variants: bool)
12921293
-> (Ty<'tcx>, Def)
12931294
{
12941295
let tcx = self.tcx();
@@ -1305,11 +1306,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
13051306
tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did)
13061307
});
13071308
if let Some(variant_def) = variant_def {
1308-
check_type_alias_enum_variants_enabled(tcx, span);
1309+
if permit_variants {
1310+
check_type_alias_enum_variants_enabled(tcx, span);
13091311

1310-
let def = Def::Variant(variant_def.did);
1311-
tcx.check_stability(def.def_id(), Some(ref_id), span);
1312-
return (ty, def);
1312+
let def = Def::Variant(variant_def.did);
1313+
tcx.check_stability(def.def_id(), Some(ref_id), span);
1314+
return (ty, def);
1315+
} else {
1316+
use rustc::lint::builtin::TYPE_VS_VARIANT_AMBIGUITY;
1317+
tcx.lint_node(
1318+
TYPE_VS_VARIANT_AMBIGUITY,
1319+
ref_id,
1320+
span,
1321+
"type vs variant ambiguity",
1322+
);
1323+
}
13131324
}
13141325
},
13151326
_ => (),
@@ -1773,7 +1784,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
17731784
} else {
17741785
Def::Err
17751786
};
1776-
self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0
1787+
self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment, false).0
17771788
}
17781789
hir::TyKind::Array(ref ty, ref length) => {
17791790
let length_def_id = tcx.hir().local_def_id(length.id);

src/librustc_typeck/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4623,7 +4623,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
46234623
Def::Err
46244624
};
46254625
let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
4626-
ty, def, segment);
4626+
ty, def, segment, true);
46274627

46284628
// Write back the new resolution.
46294629
let hir_id = self.tcx.hir().node_to_hir_id(node_id);

src/librustc_typeck/lib.rs

+15-15
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ use rustc::infer::InferOk;
111111
use rustc::lint;
112112
use rustc::middle;
113113
use rustc::session;
114-
use rustc::session::config::nightly_options;
114+
// use rustc::session::config::nightly_options;
115115
use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt};
116116
use rustc::ty::subst::Substs;
117117
use rustc::ty::{self, Ty, TyCtxt};
@@ -130,20 +130,20 @@ pub struct TypeAndSubsts<'tcx> {
130130
ty: Ty<'tcx>,
131131
}
132132

133-
fn check_type_alias_enum_variants_enabled<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
134-
span: Span) {
135-
if !tcx.features().type_alias_enum_variants {
136-
let mut err = tcx.sess.struct_span_err(
137-
span,
138-
"enum variants on type aliases are experimental"
139-
);
140-
if nightly_options::is_nightly_build() {
141-
help!(&mut err,
142-
"add `#![feature(type_alias_enum_variants)]` to the \
143-
crate attributes to enable");
144-
}
145-
err.emit();
146-
}
133+
fn check_type_alias_enum_variants_enabled<'a, 'gcx, 'tcx>(_tcx: TyCtxt<'a, 'gcx, 'tcx>,
134+
_span: Span) {
135+
// if !tcx.features().type_alias_enum_variants {
136+
// let mut err = tcx.sess.struct_span_err(
137+
// span,
138+
// "enum variants on type aliases are experimental"
139+
// );
140+
// if nightly_options::is_nightly_build() {
141+
// help!(&mut err,
142+
// "add `#![feature(type_alias_enum_variants)]` to the \
143+
// crate attributes to enable");
144+
// }
145+
// err.emit();
146+
// }
147147
}
148148

149149
fn require_c_abi_if_variadic(tcx: TyCtxt,

src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// compile-pass
12+
1113
enum Foo {
1214
Bar(i32),
1315
Baz { i: i32 },

src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr

-34
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(type_alias_enum_variants)]
2+
3+
enum E {
4+
V(u8)
5+
}
6+
7+
impl E {
8+
fn V() {}
9+
}
10+
11+
fn main() {
12+
<E>::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0061]: this function takes 1 parameter but 0 parameters were supplied
2+
--> $DIR/type-alias-enum-variants-priority-2.rs:12:5
3+
|
4+
LL | V(u8)
5+
| ----- defined here
6+
...
7+
LL | <E>::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied
8+
| ^^^^^^^^ expected 1 parameter
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0061`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(type_alias_enum_variants)]
2+
3+
enum E {
4+
V(u8)
5+
}
6+
7+
trait Tr {
8+
type V;
9+
fn f() -> Self::V;
10+
}
11+
12+
impl Tr for E {
13+
type V = u8;
14+
fn f() -> Self::V { loop {} } //~ ERROR type vs variant ambiguity
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: type vs variant ambiguity
2+
--> $DIR/type-alias-enum-variants-priority.rs:14:15
3+
|
4+
LL | fn f() -> Self::V { loop {} } //~ ERROR type vs variant ambiguity
5+
| ^^^^^^^
6+
|
7+
= note: #[forbid(type_vs_variant_ambiguity)] on by default
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)