Skip to content

Commit db9e395

Browse files
committed
Allow where clauses involving types which don't include a type parameter.
There isn't any semantic reason to disallow a `where` clause based on the fact that it doesn't contain a type parameter.
1 parent 9f227ca commit db9e395

File tree

2 files changed

+36
-46
lines changed

2 files changed

+36
-46
lines changed

src/librustc_typeck/check/wf.rs

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,6 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
115115
self.check_variances_for_type_defn(item, ast_generics);
116116
}
117117
ast::ItemTrait(_, _, _, ref items) => {
118-
let trait_predicates =
119-
ccx.tcx.lookup_predicates(local_def(item.id));
120-
reject_non_type_param_bounds(ccx.tcx, item.span, &trait_predicates);
121118
if ccx.tcx.trait_has_default_impl(local_def(item.id)) {
122119
if !items.is_empty() {
123120
wfcheck::error_380(ccx, item.span);
@@ -135,7 +132,6 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
135132
let item_def_id = local_def(item.id);
136133
let type_scheme = ccx.tcx.lookup_item_type(item_def_id);
137134
let type_predicates = ccx.tcx.lookup_predicates(item_def_id);
138-
reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates);
139135
let param_env = ccx.tcx.construct_parameter_environment(item.span,
140136
&type_scheme.generics,
141137
&type_predicates,
@@ -367,44 +363,6 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
367363
}
368364
}
369365

370-
// Reject any predicates that do not involve a type parameter.
371-
fn reject_non_type_param_bounds<'tcx>(tcx: &ty::ctxt<'tcx>,
372-
span: Span,
373-
predicates: &ty::GenericPredicates<'tcx>) {
374-
for predicate in &predicates.predicates {
375-
match predicate {
376-
&ty::Predicate::Trait(ty::Binder(ref tr)) => {
377-
let found_param = tr.input_types().iter()
378-
.flat_map(|ty| ty.walk())
379-
.any(is_ty_param);
380-
if !found_param { report_bound_error(tcx, span, tr.self_ty() )}
381-
}
382-
&ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(ty, _))) => {
383-
let found_param = ty.walk().any(|t| is_ty_param(t));
384-
if !found_param { report_bound_error(tcx, span, ty) }
385-
}
386-
_ => {}
387-
};
388-
}
389-
390-
fn report_bound_error<'t>(tcx: &ty::ctxt<'t>,
391-
span: Span,
392-
bounded_ty: ty::Ty<'t>) {
393-
span_err!(tcx.sess, span, E0193,
394-
"cannot bound type `{}`, where clause \
395-
bounds may only be attached to types involving \
396-
type parameters",
397-
bounded_ty)
398-
}
399-
400-
fn is_ty_param(ty: ty::Ty) -> bool {
401-
match &ty.sty {
402-
&ty::TyParam(_) => true,
403-
_ => false
404-
}
405-
}
406-
}
407-
408366
fn reject_shadowing_type_parameters<'tcx>(tcx: &ty::ctxt<'tcx>,
409367
span: Span,
410368
generics: &ty::Generics<'tcx>) {
@@ -445,10 +403,6 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
445403
if let ast::MethodTraitItem(_, None) = trait_item.node {
446404
match self.tcx().impl_or_trait_item(local_def(trait_item.id)) {
447405
ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
448-
reject_non_type_param_bounds(
449-
self.tcx(),
450-
trait_item.span,
451-
&ty_method.predicates);
452406
reject_shadowing_type_parameters(
453407
self.tcx(),
454408
trait_item.span,
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(rustc_attrs)]
12+
13+
use std::cmp::PartialEq;
14+
15+
struct Input<'a> {
16+
_bytes: &'a [u8],
17+
}
18+
19+
impl <'a> PartialEq for Input<'a> {
20+
fn eq(&self, _other: &Input<'a>) -> bool {
21+
panic!()
22+
}
23+
}
24+
25+
struct Input2<'a> {
26+
i: Input<'a>
27+
}
28+
29+
impl<'a, 'b> PartialEq<Input2<'b>> for Input2<'a> where Input<'a> : PartialEq<Input<'b>> {
30+
fn eq(&self, other: &Input2<'b>) -> bool {
31+
self.i == other.i
32+
}
33+
}
34+
35+
#[rustc_error]
36+
fn main() { } //~ ERROR compilation successful

0 commit comments

Comments
 (0)