Do not project when there are unconstrained impl params
This commit is contained in:
parent
ab3924b298
commit
2d602ea793
26 changed files with 214 additions and 283 deletions
|
@ -57,22 +57,24 @@ pub(crate) fn check_impl_wf(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
impl_def_id: LocalDefId,
|
impl_def_id: LocalDefId,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let min_specialization = tcx.features().min_specialization();
|
|
||||||
let mut res = Ok(());
|
|
||||||
debug_assert_matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. });
|
debug_assert_matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. });
|
||||||
res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id));
|
|
||||||
if min_specialization {
|
// Check that the args are constrained. We queryfied the check for ty/const params
|
||||||
|
// since unconstrained type/const params cause ICEs in projection, so we want to
|
||||||
|
// detect those specifically and project those to `TyKind::Error`.
|
||||||
|
let mut res = tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id);
|
||||||
|
res = res.and(enforce_impl_lifetime_params_are_constrained(tcx, impl_def_id));
|
||||||
|
|
||||||
|
if tcx.features().min_specialization() {
|
||||||
res = res.and(check_min_specialization(tcx, impl_def_id));
|
res = res.and(check_min_specialization(tcx, impl_def_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enforce_impl_params_are_constrained(
|
pub(crate) fn enforce_impl_lifetime_params_are_constrained(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
impl_def_id: LocalDefId,
|
impl_def_id: LocalDefId,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
// Every lifetime used in an associated type must be constrained.
|
|
||||||
let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
|
let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
|
||||||
if impl_self_ty.references_error() {
|
if impl_self_ty.references_error() {
|
||||||
// Don't complain about unconstrained type params when self ty isn't known due to errors.
|
// Don't complain about unconstrained type params when self ty isn't known due to errors.
|
||||||
|
@ -88,6 +90,7 @@ fn enforce_impl_params_are_constrained(
|
||||||
// Compilation must continue in order for other important diagnostics to keep showing up.
|
// Compilation must continue in order for other important diagnostics to keep showing up.
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let impl_generics = tcx.generics_of(impl_def_id);
|
let impl_generics = tcx.generics_of(impl_def_id);
|
||||||
let impl_predicates = tcx.predicates_of(impl_def_id);
|
let impl_predicates = tcx.predicates_of(impl_def_id);
|
||||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity);
|
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity);
|
||||||
|
@ -123,37 +126,22 @@ fn enforce_impl_params_are_constrained(
|
||||||
|
|
||||||
let mut res = Ok(());
|
let mut res = Ok(());
|
||||||
for param in &impl_generics.own_params {
|
for param in &impl_generics.own_params {
|
||||||
let err = match param.kind {
|
match param.kind {
|
||||||
// Disallow ANY unconstrained type parameters.
|
|
||||||
ty::GenericParamDefKind::Type { .. } => {
|
|
||||||
let param_ty = ty::ParamTy::for_def(param);
|
|
||||||
!input_parameters.contains(&cgp::Parameter::from(param_ty))
|
|
||||||
}
|
|
||||||
ty::GenericParamDefKind::Lifetime => {
|
ty::GenericParamDefKind::Lifetime => {
|
||||||
let param_lt = cgp::Parameter::from(param.to_early_bound_region_data());
|
let param_lt = cgp::Parameter::from(param.to_early_bound_region_data());
|
||||||
lifetimes_in_associated_types.contains(¶m_lt) && // (*)
|
if lifetimes_in_associated_types.contains(¶m_lt) // (*)
|
||||||
!input_parameters.contains(¶m_lt)
|
&& !input_parameters.contains(¶m_lt)
|
||||||
}
|
{
|
||||||
ty::GenericParamDefKind::Const { .. } => {
|
|
||||||
let param_ct = ty::ParamConst::for_def(param);
|
|
||||||
!input_parameters.contains(&cgp::Parameter::from(param_ct))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if err {
|
|
||||||
let const_param_note = matches!(param.kind, ty::GenericParamDefKind::Const { .. });
|
|
||||||
let mut diag = tcx.dcx().create_err(UnconstrainedGenericParameter {
|
let mut diag = tcx.dcx().create_err(UnconstrainedGenericParameter {
|
||||||
span: tcx.def_span(param.def_id),
|
span: tcx.def_span(param.def_id),
|
||||||
param_name: param.name,
|
param_name: param.name,
|
||||||
param_def_kind: tcx.def_descr(param.def_id),
|
param_def_kind: tcx.def_descr(param.def_id),
|
||||||
const_param_note,
|
const_param_note: false,
|
||||||
const_param_note2: const_param_note,
|
const_param_note2: false,
|
||||||
});
|
});
|
||||||
diag.code(E0207);
|
diag.code(E0207);
|
||||||
res = Err(diag.emit());
|
res = Err(diag.emit());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
res
|
|
||||||
|
|
||||||
// (*) This is a horrible concession to reality. I think it'd be
|
// (*) This is a horrible concession to reality. I think it'd be
|
||||||
// better to just ban unconstrained lifetimes outright, but in
|
// better to just ban unconstrained lifetimes outright, but in
|
||||||
// practice people do non-hygienic macros like:
|
// practice people do non-hygienic macros like:
|
||||||
|
@ -173,3 +161,76 @@ fn enforce_impl_params_are_constrained(
|
||||||
// associated types. I believe this is sound, because lifetimes
|
// associated types. I believe this is sound, because lifetimes
|
||||||
// used elsewhere are not projected back out.
|
// used elsewhere are not projected back out.
|
||||||
}
|
}
|
||||||
|
ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => {
|
||||||
|
// Enforced in `enforce_impl_non_lifetime_params_are_constrained`.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn enforce_impl_non_lifetime_params_are_constrained(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
impl_def_id: LocalDefId,
|
||||||
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
|
let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
|
||||||
|
if impl_self_ty.references_error() {
|
||||||
|
// Don't complain about unconstrained type params when self ty isn't known due to errors.
|
||||||
|
// (#36836)
|
||||||
|
tcx.dcx().span_delayed_bug(
|
||||||
|
tcx.def_span(impl_def_id),
|
||||||
|
format!(
|
||||||
|
"potentially unconstrained type parameters weren't evaluated: {impl_self_ty:?}",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
// This is super fishy, but our current `rustc_hir_analysis::check_crate` pipeline depends on
|
||||||
|
// `type_of` having been called much earlier, and thus this value being read from cache.
|
||||||
|
// Compilation must continue in order for other important diagnostics to keep showing up.
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let impl_generics = tcx.generics_of(impl_def_id);
|
||||||
|
let impl_predicates = tcx.predicates_of(impl_def_id);
|
||||||
|
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity);
|
||||||
|
|
||||||
|
impl_trait_ref.error_reported()?;
|
||||||
|
|
||||||
|
let mut input_parameters = cgp::parameters_for_impl(tcx, impl_self_ty, impl_trait_ref);
|
||||||
|
cgp::identify_constrained_generic_params(
|
||||||
|
tcx,
|
||||||
|
impl_predicates,
|
||||||
|
impl_trait_ref,
|
||||||
|
&mut input_parameters,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut res = Ok(());
|
||||||
|
for param in &impl_generics.own_params {
|
||||||
|
let err = match param.kind {
|
||||||
|
// Disallow ANY unconstrained type parameters.
|
||||||
|
ty::GenericParamDefKind::Type { .. } => {
|
||||||
|
let param_ty = ty::ParamTy::for_def(param);
|
||||||
|
!input_parameters.contains(&cgp::Parameter::from(param_ty))
|
||||||
|
}
|
||||||
|
ty::GenericParamDefKind::Const { .. } => {
|
||||||
|
let param_ct = ty::ParamConst::for_def(param);
|
||||||
|
!input_parameters.contains(&cgp::Parameter::from(param_ct))
|
||||||
|
}
|
||||||
|
ty::GenericParamDefKind::Lifetime => {
|
||||||
|
// Enforced in `enforce_impl_type_params_are_constrained`.
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if err {
|
||||||
|
let const_param_note = matches!(param.kind, ty::GenericParamDefKind::Const { .. });
|
||||||
|
let mut diag = tcx.dcx().create_err(UnconstrainedGenericParameter {
|
||||||
|
span: tcx.def_span(param.def_id),
|
||||||
|
param_name: param.name,
|
||||||
|
param_def_kind: tcx.def_descr(param.def_id),
|
||||||
|
const_param_note,
|
||||||
|
const_param_note2: const_param_note,
|
||||||
|
});
|
||||||
|
diag.code(E0207);
|
||||||
|
res = Err(diag.emit());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
|
@ -128,6 +128,8 @@ pub fn provide(providers: &mut Providers) {
|
||||||
hir_wf_check::provide(providers);
|
hir_wf_check::provide(providers);
|
||||||
*providers = Providers {
|
*providers = Providers {
|
||||||
inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item,
|
inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item,
|
||||||
|
enforce_impl_non_lifetime_params_are_constrained:
|
||||||
|
impl_wf_check::enforce_impl_non_lifetime_params_are_constrained,
|
||||||
..*providers
|
..*providers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1719,6 +1719,11 @@ rustc_queries! {
|
||||||
ensure_forwards_result_if_red
|
ensure_forwards_result_if_red
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query enforce_impl_non_lifetime_params_are_constrained(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
|
||||||
|
desc { |tcx| "checking that `{}`'s generics are constrained by the impl header", tcx.def_path_str(key) }
|
||||||
|
ensure_forwards_result_if_red
|
||||||
|
}
|
||||||
|
|
||||||
// The `DefId`s of all non-generic functions and statics in the given crate
|
// The `DefId`s of all non-generic functions and statics in the given crate
|
||||||
// that can be reached from outside the crate.
|
// that can be reached from outside the crate.
|
||||||
//
|
//
|
||||||
|
|
|
@ -950,13 +950,12 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||||
//
|
//
|
||||||
// NOTE: This should be kept in sync with the similar code in
|
// NOTE: This should be kept in sync with the similar code in
|
||||||
// `rustc_ty_utils::instance::resolve_associated_item()`.
|
// `rustc_ty_utils::instance::resolve_associated_item()`.
|
||||||
let node_item = specialization_graph::assoc_def(
|
match specialization_graph::assoc_def(
|
||||||
selcx.tcx(),
|
selcx.tcx(),
|
||||||
impl_data.impl_def_id,
|
impl_data.impl_def_id,
|
||||||
obligation.predicate.def_id,
|
obligation.predicate.def_id,
|
||||||
)
|
) {
|
||||||
.map_err(|ErrorGuaranteed { .. }| ())?;
|
Ok(node_item) => {
|
||||||
|
|
||||||
if node_item.is_final() {
|
if node_item.is_final() {
|
||||||
// Non-specializable items are always projectable.
|
// Non-specializable items are always projectable.
|
||||||
true
|
true
|
||||||
|
@ -972,19 +971,26 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||||
debug!(
|
debug!(
|
||||||
assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
|
assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
|
||||||
?obligation.predicate,
|
?obligation.predicate,
|
||||||
"assemble_candidates_from_impls: not eligible due to default",
|
"not eligible due to default",
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
TypingMode::PostAnalysis => {
|
TypingMode::PostAnalysis => {
|
||||||
// NOTE(eddyb) inference variables can resolve to parameters, so
|
// NOTE(eddyb) inference variables can resolve to parameters, so
|
||||||
// assume `poly_trait_ref` isn't monomorphic, if it contains any.
|
// assume `poly_trait_ref` isn't monomorphic, if it contains any.
|
||||||
let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref);
|
let poly_trait_ref =
|
||||||
|
selcx.infcx.resolve_vars_if_possible(trait_ref);
|
||||||
!poly_trait_ref.still_further_specializable()
|
!poly_trait_ref.still_further_specializable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Always project `ErrorGuaranteed`, since this will just help
|
||||||
|
// us propagate `TyKind::Error` around which suppresses ICEs
|
||||||
|
// and spurious, unrelated inference errors.
|
||||||
|
Err(ErrorGuaranteed { .. }) => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
ImplSource::Builtin(BuiltinImplSource::Misc, _) => {
|
ImplSource::Builtin(BuiltinImplSource::Misc, _) => {
|
||||||
// While a builtin impl may be known to exist, the associated type may not yet
|
// While a builtin impl may be known to exist, the associated type may not yet
|
||||||
// be known. Any type with multiple potential associated types is therefore
|
// be known. Any type with multiple potential associated types is therefore
|
||||||
|
@ -2014,7 +2020,6 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
||||||
Ok(assoc_ty) => assoc_ty,
|
Ok(assoc_ty) => assoc_ty,
|
||||||
Err(guar) => return Progress::error(tcx, guar),
|
Err(guar) => return Progress::error(tcx, guar),
|
||||||
};
|
};
|
||||||
|
|
||||||
if !assoc_ty.item.defaultness(tcx).has_value() {
|
if !assoc_ty.item.defaultness(tcx).has_value() {
|
||||||
// This means that the impl is missing a definition for the
|
// This means that the impl is missing a definition for the
|
||||||
// associated type. This error will be reported by the type
|
// associated type. This error will be reported by the type
|
||||||
|
|
|
@ -376,6 +376,12 @@ pub(crate) fn assoc_def(
|
||||||
// If there is no such item in that impl, this function will fail with a
|
// If there is no such item in that impl, this function will fail with a
|
||||||
// cycle error if the specialization graph is currently being built.
|
// cycle error if the specialization graph is currently being built.
|
||||||
if let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&assoc_def_id) {
|
if let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&assoc_def_id) {
|
||||||
|
// Ensure that the impl is constrained, otherwise projection may give us
|
||||||
|
// bad unconstrained infer vars.
|
||||||
|
if let Some(impl_def_id) = impl_def_id.as_local() {
|
||||||
|
tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
|
||||||
|
}
|
||||||
|
|
||||||
let item = tcx.associated_item(impl_item_id);
|
let item = tcx.associated_item(impl_item_id);
|
||||||
let impl_node = Node::Impl(impl_def_id);
|
let impl_node = Node::Impl(impl_def_id);
|
||||||
return Ok(LeafDef {
|
return Ok(LeafDef {
|
||||||
|
@ -391,6 +397,14 @@ pub(crate) fn assoc_def(
|
||||||
|
|
||||||
let ancestors = trait_def.ancestors(tcx, impl_def_id)?;
|
let ancestors = trait_def.ancestors(tcx, impl_def_id)?;
|
||||||
if let Some(assoc_item) = ancestors.leaf_def(tcx, assoc_def_id) {
|
if let Some(assoc_item) = ancestors.leaf_def(tcx, assoc_def_id) {
|
||||||
|
// Ensure that the impl is constrained, otherwise projection may give us
|
||||||
|
// bad unconstrained infer vars.
|
||||||
|
if assoc_item.item.container == ty::AssocItemContainer::Impl
|
||||||
|
&& let Some(impl_def_id) = assoc_item.item.container_id(tcx).as_local()
|
||||||
|
{
|
||||||
|
tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(assoc_item)
|
Ok(assoc_item)
|
||||||
} else {
|
} else {
|
||||||
// This is saying that neither the trait nor
|
// This is saying that neither the trait nor
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
//@ known-bug: #123141
|
|
||||||
|
|
||||||
trait Trait {
|
|
||||||
fn next(self) -> Self::Item;
|
|
||||||
type Item;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Foo<T: ?Sized>(T);
|
|
||||||
|
|
||||||
impl<T: ?Sized, U> Trait for Foo<U> {
|
|
||||||
type Item = Foo<T>;
|
|
||||||
fn next(self) -> Self::Item {
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn opaque() -> impl Trait {
|
|
||||||
Foo::<_>(10_u32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
opaque().next();
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
//@ known-bug: rust-lang/rust#125874
|
|
||||||
pub trait A {}
|
|
||||||
|
|
||||||
pub trait Mirror {
|
|
||||||
type Assoc: ?Sized;
|
|
||||||
}
|
|
||||||
impl<T: ?Sized> Mirror for dyn A {
|
|
||||||
type Assoc = T;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Bar {
|
|
||||||
foo: <dyn A + 'static as Mirror>::Assoc,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() {
|
|
||||||
let strct = Bar { foo: 3 };
|
|
||||||
|
|
||||||
match strct {
|
|
||||||
Bar { foo: 1, .. } => {}
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
//@ known-bug: rust-lang/rust#126942
|
|
||||||
struct Thing;
|
|
||||||
|
|
||||||
pub trait Every {
|
|
||||||
type Assoc;
|
|
||||||
}
|
|
||||||
impl<T: ?Sized> Every for Thing {
|
|
||||||
type Assoc = T;
|
|
||||||
}
|
|
||||||
|
|
||||||
static I: <Thing as Every>::Assoc = 3;
|
|
|
@ -1,12 +0,0 @@
|
||||||
//@ known-bug: #127804
|
|
||||||
|
|
||||||
struct Thing;
|
|
||||||
|
|
||||||
pub trait Every {
|
|
||||||
type Assoc;
|
|
||||||
}
|
|
||||||
impl<T: ?Sized> Every for Thing {
|
|
||||||
type Assoc = T;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn foo(_: <Thing as Every>::Assoc) {}
|
|
|
@ -1,13 +0,0 @@
|
||||||
//@ known-bug: #130967
|
|
||||||
|
|
||||||
trait Producer {
|
|
||||||
type Produced;
|
|
||||||
fn make_one() -> Self::Produced;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: ?Sized> Producer for () {
|
|
||||||
type Produced = Option<E>;
|
|
||||||
fn make_one() -> Self::Produced {
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,73 +22,7 @@ help: consider adding an explicit lifetime bound
|
||||||
LL | type Output<'a> = FooRef<'a, U> where Self: 'a, U: 'a;
|
LL | type Output<'a> = FooRef<'a, U> where Self: 'a, U: 'a;
|
||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
error[E0309]: the parameter type `T` may not live long enough
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/issue-87735.rs:31:15
|
|
||||||
|
|
|
||||||
LL | impl<'b, T, U> AsRef2 for Foo<T>
|
|
||||||
| -- the parameter type `T` must be valid for the lifetime `'b` as defined here...
|
|
||||||
...
|
|
||||||
LL | T: AsRef2<Output<'b> = &'b [U]>,
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
|
|
||||||
|
|
|
||||||
note: ...that is required by this bound
|
|
||||||
--> $DIR/issue-87735.rs:7:31
|
|
||||||
|
|
|
||||||
LL | type Output<'a> where Self: 'a;
|
|
||||||
| ^^
|
|
||||||
help: consider adding an explicit lifetime bound
|
|
||||||
|
|
|
||||||
LL | T: AsRef2<Output<'b> = &'b [U]> + 'b,
|
|
||||||
| ++++
|
|
||||||
|
|
||||||
error[E0309]: the parameter type `T` may not live long enough
|
|
||||||
--> $DIR/issue-87735.rs:36:31
|
|
||||||
|
|
|
||||||
LL | impl<'b, T, U> AsRef2 for Foo<T>
|
|
||||||
| -- the parameter type `T` must be valid for the lifetime `'b` as defined here...
|
|
||||||
...
|
|
||||||
LL | fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
|
|
||||||
| ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
|
|
||||||
|
|
|
||||||
note: ...that is required by this bound
|
|
||||||
--> $DIR/issue-87735.rs:7:31
|
|
||||||
|
|
|
||||||
LL | type Output<'a> where Self: 'a;
|
|
||||||
| ^^
|
|
||||||
help: consider adding an explicit lifetime bound
|
|
||||||
|
|
|
||||||
LL | T: AsRef2<Output<'b> = &'b [U]> + 'b,
|
|
||||||
| ++++
|
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
|
||||||
--> $DIR/issue-87735.rs:37:5
|
|
||||||
|
|
|
||||||
LL | impl<'b, T, U> AsRef2 for Foo<T>
|
|
||||||
| -- lifetime `'b` defined here
|
|
||||||
...
|
|
||||||
LL | fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
|
|
||||||
| -- lifetime `'a` defined here
|
|
||||||
LL | FooRef(self.0.as_ref2())
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
|
||||||
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
|
||||||
--> $DIR/issue-87735.rs:37:12
|
|
||||||
|
|
|
||||||
LL | impl<'b, T, U> AsRef2 for Foo<T>
|
|
||||||
| -- lifetime `'b` defined here
|
|
||||||
...
|
|
||||||
LL | fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
|
|
||||||
| -- lifetime `'a` defined here
|
|
||||||
LL | FooRef(self.0.as_ref2())
|
|
||||||
| ^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
|
||||||
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
|
||||||
|
|
||||||
help: `'b` and `'a` must be the same: replace one with the other
|
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0207, E0309.
|
Some errors have detailed explanations: E0207, E0309.
|
||||||
For more information about an error, try `rustc --explain E0207`.
|
For more information about an error, try `rustc --explain E0207`.
|
||||||
|
|
|
@ -13,7 +13,6 @@ impl<T: ?Sized> Mirror for () {
|
||||||
|
|
||||||
pub trait First {
|
pub trait First {
|
||||||
async fn first() -> <() as Mirror>::Assoc;
|
async fn first() -> <() as Mirror>::Assoc;
|
||||||
//~^ ERROR type annotations needed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl First for () {
|
impl First for () {
|
||||||
|
|
|
@ -4,13 +4,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
|
||||||
LL | impl<T: ?Sized> Mirror for () {
|
LL | impl<T: ?Sized> Mirror for () {
|
||||||
| ^ unconstrained type parameter
|
| ^ unconstrained type parameter
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/refine-resolution-errors.rs:15:5
|
|
||||||
|
|
|
||||||
LL | async fn first() -> <() as Mirror>::Assoc;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0207`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0207, E0282.
|
|
||||||
For more information about an error, try `rustc --explain E0207`.
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ impl<T> X for () {
|
||||||
//~^ ERROR `T` is not constrained by the impl trait, self type, or predicates
|
//~^ ERROR `T` is not constrained by the impl trait, self type, or predicates
|
||||||
type I = impl Sized;
|
type I = impl Sized;
|
||||||
fn f() -> Self::I {}
|
fn f() -> Self::I {}
|
||||||
//~^ ERROR type annotations needed
|
|
||||||
//~| ERROR type annotations needed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -4,19 +4,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
|
||||||
LL | impl<T> X for () {
|
LL | impl<T> X for () {
|
||||||
| ^ unconstrained type parameter
|
| ^ unconstrained type parameter
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/issue-87340.rs:11:23
|
|
||||||
|
|
|
||||||
LL | fn f() -> Self::I {}
|
|
||||||
| ^^ cannot infer type for type parameter `T`
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
For more information about this error, try `rustc --explain E0207`.
|
||||||
--> $DIR/issue-87340.rs:11:15
|
|
||||||
|
|
|
||||||
LL | fn f() -> Self::I {}
|
|
||||||
| ^^^^^^^ cannot infer type for type parameter `T`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0207, E0282.
|
|
||||||
For more information about an error, try `rustc --explain E0207`.
|
|
||||||
|
|
|
@ -7,6 +7,12 @@ LL | impl<T> Foo<T> for [isize; 0] {
|
||||||
LL | impl<T, U> Foo<T> for U {
|
LL | impl<T, U> Foo<T> for U {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]`
|
||||||
|
|
||||||
|
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
|
||||||
|
--> $DIR/impl-unused-tps.rs:32:9
|
||||||
|
|
|
||||||
|
LL | impl<T, U> Bar for T {
|
||||||
|
| ^ unconstrained type parameter
|
||||||
|
|
||||||
error[E0119]: conflicting implementations of trait `Bar`
|
error[E0119]: conflicting implementations of trait `Bar`
|
||||||
--> $DIR/impl-unused-tps.rs:40:1
|
--> $DIR/impl-unused-tps.rs:40:1
|
||||||
|
|
|
|
||||||
|
@ -46,12 +52,6 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self
|
||||||
LL | impl<T, U> Foo<T> for [isize; 1] {
|
LL | impl<T, U> Foo<T> for [isize; 1] {
|
||||||
| ^ unconstrained type parameter
|
| ^ unconstrained type parameter
|
||||||
|
|
||||||
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
|
|
||||||
--> $DIR/impl-unused-tps.rs:32:9
|
|
||||||
|
|
|
||||||
LL | impl<T, U> Bar for T {
|
|
||||||
| ^ unconstrained type parameter
|
|
||||||
|
|
||||||
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
|
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
|
||||||
--> $DIR/impl-unused-tps.rs:40:9
|
--> $DIR/impl-unused-tps.rs:40:9
|
||||||
|
|
|
|
||||||
|
|
17
tests/ui/traits/unconstrained-projection-normalization-2.rs
Normal file
17
tests/ui/traits/unconstrained-projection-normalization-2.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Make sure we don't ICE in `normalize_erasing_regions` when normalizing
|
||||||
|
// an associated type in an impl with unconstrained non-lifetime params.
|
||||||
|
// (This time in a function signature)
|
||||||
|
|
||||||
|
struct Thing;
|
||||||
|
|
||||||
|
pub trait Every {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
impl<T: ?Sized> Every for Thing {
|
||||||
|
//~^ ERROR the type parameter `T` is not constrained
|
||||||
|
type Assoc = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(_: <Thing as Every>::Assoc) {}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
|
||||||
|
--> $DIR/unconstrained-projection-normalization-2.rs:10:6
|
||||||
|
|
|
||||||
|
LL | impl<T: ?Sized> Every for Thing {
|
||||||
|
| ^ unconstrained type parameter
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0207`.
|
16
tests/ui/traits/unconstrained-projection-normalization.rs
Normal file
16
tests/ui/traits/unconstrained-projection-normalization.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Make sure we don't ICE in `normalize_erasing_regions` when normalizing
|
||||||
|
// an associated type in an impl with unconstrained non-lifetime params.
|
||||||
|
|
||||||
|
struct Thing;
|
||||||
|
|
||||||
|
pub trait Every {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
impl<T: ?Sized> Every for Thing {
|
||||||
|
//~^ ERROR the type parameter `T` is not constrained
|
||||||
|
type Assoc = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
static I: <Thing as Every>::Assoc = 3;
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
|
||||||
|
--> $DIR/unconstrained-projection-normalization.rs:9:6
|
||||||
|
|
|
||||||
|
LL | impl<T: ?Sized> Every for Thing {
|
||||||
|
| ^ unconstrained type parameter
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0207`.
|
|
@ -42,7 +42,6 @@ impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
|
||||||
//~^ ERROR the type parameter `T` is not constrained by the impl
|
//~^ ERROR the type parameter `T` is not constrained by the impl
|
||||||
type O = T;
|
type O = T;
|
||||||
fn my_index(self) -> Self::O {
|
fn my_index(self) -> Self::O {
|
||||||
//~^ ERROR item does not constrain
|
|
||||||
MyFrom::my_from(self.0).ok().unwrap()
|
MyFrom::my_from(self.0).ok().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,19 +17,6 @@ note: this opaque type is in the signature
|
||||||
LL | type DummyT<T> = impl F;
|
LL | type DummyT<T> = impl F;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:44:8
|
|
||||||
|
|
|
||||||
LL | fn my_index(self) -> Self::O {
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
|
||||||
note: this opaque type is in the signature
|
|
||||||
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:20:18
|
|
||||||
|
|
|
||||||
LL | type DummyT<T> = impl F;
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0207`.
|
For more information about this error, try `rustc --explain E0207`.
|
||||||
|
|
|
@ -12,8 +12,6 @@ impl<T> X for () {
|
||||||
//~^ ERROR the type parameter `T` is not constrained
|
//~^ ERROR the type parameter `T` is not constrained
|
||||||
type I = impl Sized;
|
type I = impl Sized;
|
||||||
fn f() -> Self::I {}
|
fn f() -> Self::I {}
|
||||||
//~^ ERROR type annotations needed
|
|
||||||
//~| ERROR type annotations needed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -4,19 +4,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
|
||||||
LL | impl<T> X for () {
|
LL | impl<T> X for () {
|
||||||
| ^ unconstrained type parameter
|
| ^ unconstrained type parameter
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/impl-with-unconstrained-param.rs:14:23
|
|
||||||
|
|
|
||||||
LL | fn f() -> Self::I {}
|
|
||||||
| ^^ cannot infer type for type parameter `T`
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
For more information about this error, try `rustc --explain E0207`.
|
||||||
--> $DIR/impl-with-unconstrained-param.rs:14:15
|
|
||||||
|
|
|
||||||
LL | fn f() -> Self::I {}
|
|
||||||
| ^^^^^^^ cannot infer type for type parameter `T`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0207, E0282.
|
|
||||||
For more information about an error, try `rustc --explain E0207`.
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ impl<T> Allocator for DefaultAllocator {
|
||||||
type A = impl Fn(<DefaultAllocator as Allocator>::Buffer);
|
type A = impl Fn(<DefaultAllocator as Allocator>::Buffer);
|
||||||
|
|
||||||
fn foo() -> A {
|
fn foo() -> A {
|
||||||
//~^ ERROR: type annotations needed
|
|
||||||
|_| ()
|
|_| ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
|
||||||
LL | impl<T> Allocator for DefaultAllocator {
|
LL | impl<T> Allocator for DefaultAllocator {
|
||||||
| ^ unconstrained type parameter
|
| ^ unconstrained type parameter
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/issue-74244.rs:16:13
|
|
||||||
|
|
|
||||||
LL | fn foo() -> A {
|
|
||||||
| ^ cannot infer type for type parameter `T`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0207`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0207, E0282.
|
|
||||||
For more information about an error, try `rustc --explain E0207`.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue