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| {
|
||||
if let ty::TyAnon(def_id, substs) = ty.sty {
|
||||
trace!("check_existential_types: anon_ty, {:?}, {:?}", def_id, substs);
|
||||
let anon_node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
if may_define_existential_type(tcx, fn_def_id, anon_node_id) {
|
||||
let generics = tcx.generics_of(def_id);
|
||||
trace!("check_existential_types may define. Generics: {:#?}", generics);
|
||||
for (subst, param) in substs.iter().zip(&generics.params) {
|
||||
if let ty::subst::UnpackedKind::Type(ty) = subst.unpack() {
|
||||
match ty.sty {
|
||||
ty::TyParam(..) => {},
|
||||
// prevent `fn foo() -> Foo<u32>` from being defining
|
||||
_ => {
|
||||
tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
"non-defining existential type use in defining scope",
|
||||
)
|
||||
.span_note(
|
||||
tcx.def_span(param.def_id),
|
||||
&format!(
|
||||
"used non-generic type {} for generic parameter",
|
||||
ty,
|
||||
),
|
||||
)
|
||||
.emit();
|
||||
return tcx.types.err;
|
||||
},
|
||||
} // match ty
|
||||
} // if let Type = subst
|
||||
} // for (subst, param)
|
||||
} // if may_define_existential_type
|
||||
let generics = tcx.generics_of(def_id);
|
||||
// only check named existential types
|
||||
if generics.parent.is_none() {
|
||||
let anon_node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
if may_define_existential_type(tcx, fn_def_id, anon_node_id) {
|
||||
trace!("check_existential_types may define. Generics: {:#?}", generics);
|
||||
for (subst, param) in substs.iter().zip(&generics.params) {
|
||||
if let ty::subst::UnpackedKind::Type(ty) = subst.unpack() {
|
||||
match ty.sty {
|
||||
ty::TyParam(..) => {},
|
||||
// prevent `fn foo() -> Foo<u32>` from being defining
|
||||
_ => {
|
||||
tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
"non-defining existential type use \
|
||||
in defining scope",
|
||||
)
|
||||
.span_note(
|
||||
tcx.def_span(param.def_id),
|
||||
&format!(
|
||||
"used non-generic type {} for \
|
||||
generic parameter",
|
||||
ty,
|
||||
),
|
||||
)
|
||||
.emit();
|
||||
return tcx.types.err;
|
||||
},
|
||||
} // 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
|
||||
// so the parameters given by the function need to fulfil them
|
||||
// ```rust
|
||||
// existential type Foo<T: Bar>: 'static;
|
||||
// fn foo<U>() -> Foo<U> { .. *}
|
||||
// ```
|
||||
// becomes
|
||||
// ```rust
|
||||
// existential type Foo<T: Bar>: 'static;
|
||||
// fn foo<U: Bar>() -> Foo<U> { .. *}
|
||||
// ```
|
||||
let predicates = tcx.predicates_of(def_id);
|
||||
trace!("check_existential_types may define. adding predicates: {:#?}", predicates);
|
||||
for &pred in predicates.predicates.iter() {
|
||||
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);
|
||||
// now register the bounds on the parameters of the existential type
|
||||
// so the parameters given by the function need to fulfil them
|
||||
// ```rust
|
||||
// existential type Foo<T: Bar>: 'static;
|
||||
// fn foo<U>() -> Foo<U> { .. *}
|
||||
// ```
|
||||
// becomes
|
||||
// ```rust
|
||||
// existential type Foo<T: Bar>: 'static;
|
||||
// fn foo<U: Bar>() -> Foo<U> { .. *}
|
||||
// ```
|
||||
let predicates = tcx.predicates_of(def_id);
|
||||
trace!(
|
||||
"check_existential_types may define. adding predicates: {:#?}",
|
||||
predicates,
|
||||
);
|
||||
for &pred in predicates.predicates.iter() {
|
||||
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
|
||||
ty
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user