Only check existential types, not the desugared impl Trait
This commit is contained in:
parent
3e215a3c87
commit
2ed1aca101
@ -549,57 +549,65 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
|
|||||||
fldop: |ty| {
|
fldop: |ty| {
|
||||||
if let ty::TyAnon(def_id, substs) = ty.sty {
|
if let ty::TyAnon(def_id, substs) = ty.sty {
|
||||||
trace!("check_existential_types: anon_ty, {:?}, {:?}", def_id, substs);
|
trace!("check_existential_types: anon_ty, {:?}, {:?}", def_id, substs);
|
||||||
let anon_node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
let generics = tcx.generics_of(def_id);
|
||||||
if may_define_existential_type(tcx, fn_def_id, anon_node_id) {
|
// only check named existential types
|
||||||
let generics = tcx.generics_of(def_id);
|
if generics.parent.is_none() {
|
||||||
trace!("check_existential_types may define. Generics: {:#?}", generics);
|
let anon_node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||||
for (subst, param) in substs.iter().zip(&generics.params) {
|
if may_define_existential_type(tcx, fn_def_id, anon_node_id) {
|
||||||
if let ty::subst::UnpackedKind::Type(ty) = subst.unpack() {
|
trace!("check_existential_types may define. Generics: {:#?}", generics);
|
||||||
match ty.sty {
|
for (subst, param) in substs.iter().zip(&generics.params) {
|
||||||
ty::TyParam(..) => {},
|
if let ty::subst::UnpackedKind::Type(ty) = subst.unpack() {
|
||||||
// prevent `fn foo() -> Foo<u32>` from being defining
|
match ty.sty {
|
||||||
_ => {
|
ty::TyParam(..) => {},
|
||||||
tcx
|
// prevent `fn foo() -> Foo<u32>` from being defining
|
||||||
.sess
|
_ => {
|
||||||
.struct_span_err(
|
tcx
|
||||||
span,
|
.sess
|
||||||
"non-defining existential type use in defining scope",
|
.struct_span_err(
|
||||||
)
|
span,
|
||||||
.span_note(
|
"non-defining existential type use \
|
||||||
tcx.def_span(param.def_id),
|
in defining scope",
|
||||||
&format!(
|
)
|
||||||
"used non-generic type {} for generic parameter",
|
.span_note(
|
||||||
ty,
|
tcx.def_span(param.def_id),
|
||||||
),
|
&format!(
|
||||||
)
|
"used non-generic type {} for \
|
||||||
.emit();
|
generic parameter",
|
||||||
return tcx.types.err;
|
ty,
|
||||||
},
|
),
|
||||||
} // match ty
|
)
|
||||||
} // if let Type = subst
|
.emit();
|
||||||
} // for (subst, param)
|
return tcx.types.err;
|
||||||
} // if may_define_existential_type
|
},
|
||||||
|
} // match ty
|
||||||
|
} // if let Type = subst
|
||||||
|
} // for (subst, param)
|
||||||
|
} // if may_define_existential_type
|
||||||
|
|
||||||
// now register the bounds on the parameters of the existential type
|
// now register the bounds on the parameters of the existential type
|
||||||
// so the parameters given by the function need to fulfil them
|
// so the parameters given by the function need to fulfil them
|
||||||
// ```rust
|
// ```rust
|
||||||
// existential type Foo<T: Bar>: 'static;
|
// existential type Foo<T: Bar>: 'static;
|
||||||
// fn foo<U>() -> Foo<U> { .. *}
|
// fn foo<U>() -> Foo<U> { .. *}
|
||||||
// ```
|
// ```
|
||||||
// becomes
|
// becomes
|
||||||
// ```rust
|
// ```rust
|
||||||
// existential type Foo<T: Bar>: 'static;
|
// existential type Foo<T: Bar>: 'static;
|
||||||
// fn foo<U: Bar>() -> Foo<U> { .. *}
|
// fn foo<U: Bar>() -> Foo<U> { .. *}
|
||||||
// ```
|
// ```
|
||||||
let predicates = tcx.predicates_of(def_id);
|
let predicates = tcx.predicates_of(def_id);
|
||||||
trace!("check_existential_types may define. adding predicates: {:#?}", predicates);
|
trace!(
|
||||||
for &pred in predicates.predicates.iter() {
|
"check_existential_types may define. adding predicates: {:#?}",
|
||||||
let substituted_pred = pred.subst(fcx.tcx, substs);
|
predicates,
|
||||||
// Avoid duplication of predicates that contain no parameters, for example.
|
);
|
||||||
if !predicates.predicates.contains(&substituted_pred) {
|
for &pred in predicates.predicates.iter() {
|
||||||
substituted_predicates.push(substituted_pred);
|
let substituted_pred = pred.subst(fcx.tcx, substs);
|
||||||
|
// Avoid duplication of predicates that contain no parameters, for example.
|
||||||
|
if !predicates.predicates.contains(&substituted_pred) {
|
||||||
|
substituted_predicates.push(substituted_pred);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} // if is_named_existential_type
|
||||||
} // if let TyAnon
|
} // if let TyAnon
|
||||||
ty
|
ty
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user