implied_bounds: clarify our assumptions
This commit is contained in:
parent
b7a8496a07
commit
4fe666ee64
22 changed files with 251 additions and 172 deletions
|
@ -765,6 +765,14 @@ rustc_queries! {
|
||||||
desc { |tcx| "processing `{}`", tcx.def_path_str(key.to_def_id()) }
|
desc { |tcx| "processing `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the types assumed to be well formed while "inside" of the given item.
|
||||||
|
///
|
||||||
|
/// Note that we've liberated the late bound regions of function signatures, so
|
||||||
|
/// this can not be used to check whether these types are well formed.
|
||||||
|
query assumed_wf_types(key: DefId) -> &'tcx ty::List<Ty<'tcx>> {
|
||||||
|
desc { |tcx| "computing the implied bounds of {}", tcx.def_path_str(key) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Computes the signature of the function.
|
/// Computes the signature of the function.
|
||||||
query fn_sig(key: DefId) -> ty::PolyFnSig<'tcx> {
|
query fn_sig(key: DefId) -> ty::PolyFnSig<'tcx> {
|
||||||
desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) }
|
||||||
|
|
60
compiler/rustc_ty_utils/src/implied_bounds.rs
Normal file
60
compiler/rustc_ty_utils/src/implied_bounds.rs
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
use crate::rustc_middle::ty::DefIdTree;
|
||||||
|
use rustc_hir::{def::DefKind, def_id::DefId};
|
||||||
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
|
|
||||||
|
pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
|
*providers = ty::query::Providers { assumed_wf_types, ..*providers };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::List<Ty<'tcx>> {
|
||||||
|
match tcx.def_kind(def_id) {
|
||||||
|
DefKind::Fn => {
|
||||||
|
let sig = tcx.fn_sig(def_id);
|
||||||
|
let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig);
|
||||||
|
liberated_sig.inputs_and_output
|
||||||
|
}
|
||||||
|
DefKind::AssocFn => {
|
||||||
|
let sig = tcx.fn_sig(def_id);
|
||||||
|
let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig);
|
||||||
|
let mut assumed_wf_types: Vec<_> =
|
||||||
|
tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into();
|
||||||
|
assumed_wf_types.extend(liberated_sig.inputs_and_output);
|
||||||
|
tcx.intern_type_list(&assumed_wf_types)
|
||||||
|
}
|
||||||
|
DefKind::Impl => match tcx.impl_trait_ref(def_id) {
|
||||||
|
Some(trait_ref) => {
|
||||||
|
let types: Vec<_> = trait_ref.substs.types().collect();
|
||||||
|
tcx.intern_type_list(&types)
|
||||||
|
}
|
||||||
|
// Only the impl self type
|
||||||
|
None => tcx.intern_type_list(&[tcx.type_of(def_id)]),
|
||||||
|
},
|
||||||
|
DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)),
|
||||||
|
DefKind::Mod
|
||||||
|
| DefKind::Struct
|
||||||
|
| DefKind::Union
|
||||||
|
| DefKind::Enum
|
||||||
|
| DefKind::Variant
|
||||||
|
| DefKind::Trait
|
||||||
|
| DefKind::TyAlias
|
||||||
|
| DefKind::ForeignTy
|
||||||
|
| DefKind::TraitAlias
|
||||||
|
| DefKind::TyParam
|
||||||
|
| DefKind::Const
|
||||||
|
| DefKind::ConstParam
|
||||||
|
| DefKind::Static(_)
|
||||||
|
| DefKind::Ctor(_, _)
|
||||||
|
| DefKind::Macro(_)
|
||||||
|
| DefKind::ExternCrate
|
||||||
|
| DefKind::Use
|
||||||
|
| DefKind::ForeignMod
|
||||||
|
| DefKind::AnonConst
|
||||||
|
| DefKind::InlineConst
|
||||||
|
| DefKind::OpaqueTy
|
||||||
|
| DefKind::Field
|
||||||
|
| DefKind::LifetimeParam
|
||||||
|
| DefKind::GlobalAsm
|
||||||
|
| DefKind::Closure
|
||||||
|
| DefKind::Generator => ty::List::empty(),
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ use rustc_middle::ty::query::Providers;
|
||||||
mod assoc;
|
mod assoc;
|
||||||
mod common_traits;
|
mod common_traits;
|
||||||
mod consts;
|
mod consts;
|
||||||
|
mod implied_bounds;
|
||||||
pub mod instance;
|
pub mod instance;
|
||||||
mod needs_drop;
|
mod needs_drop;
|
||||||
pub mod representability;
|
pub mod representability;
|
||||||
|
@ -30,6 +31,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
assoc::provide(providers);
|
assoc::provide(providers);
|
||||||
common_traits::provide(providers);
|
common_traits::provide(providers);
|
||||||
consts::provide(providers);
|
consts::provide(providers);
|
||||||
|
implied_bounds::provide(providers);
|
||||||
needs_drop::provide(providers);
|
needs_drop::provide(providers);
|
||||||
ty::provide(providers);
|
ty::provide(providers);
|
||||||
instance::provide(providers);
|
instance::provide(providers);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use super::potentially_plural_count;
|
use super::potentially_plural_count;
|
||||||
use crate::check::regionck::OutlivesEnvironmentExt;
|
use crate::check::regionck::OutlivesEnvironmentExt;
|
||||||
use crate::check::wfcheck;
|
|
||||||
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
|
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed};
|
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed};
|
||||||
|
@ -1445,14 +1444,24 @@ pub fn check_type_bounds<'tcx>(
|
||||||
};
|
};
|
||||||
debug!(?normalize_param_env);
|
debug!(?normalize_param_env);
|
||||||
|
|
||||||
|
let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local());
|
||||||
let impl_ty_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
|
let impl_ty_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
|
||||||
let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
|
let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
|
||||||
|
|
||||||
tcx.infer_ctxt().enter(move |infcx| {
|
tcx.infer_ctxt().enter(move |infcx| {
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
|
|
||||||
|
let assumed_wf_types = tcx.assumed_wf_types(impl_ty.def_id);
|
||||||
|
let mut implied_bounds = FxHashSet::default();
|
||||||
|
let cause = ObligationCause::misc(impl_ty_span, impl_ty_hir_id);
|
||||||
|
for ty in assumed_wf_types {
|
||||||
|
implied_bounds.insert(ty);
|
||||||
|
let normalized = ocx.normalize(cause.clone(), param_env, ty);
|
||||||
|
implied_bounds.insert(normalized);
|
||||||
|
}
|
||||||
|
let implied_bounds = implied_bounds;
|
||||||
|
|
||||||
let mut selcx = traits::SelectionContext::new(&infcx);
|
let mut selcx = traits::SelectionContext::new(&infcx);
|
||||||
let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local());
|
|
||||||
let normalize_cause = ObligationCause::new(
|
let normalize_cause = ObligationCause::new(
|
||||||
impl_ty_span,
|
impl_ty_span,
|
||||||
impl_ty_hir_id,
|
impl_ty_hir_id,
|
||||||
|
@ -1508,15 +1517,6 @@ pub fn check_type_bounds<'tcx>(
|
||||||
|
|
||||||
// Finally, resolve all regions. This catches wily misuses of
|
// Finally, resolve all regions. This catches wily misuses of
|
||||||
// lifetime parameters.
|
// lifetime parameters.
|
||||||
let implied_bounds = match impl_ty.container {
|
|
||||||
ty::TraitContainer => FxHashSet::default(),
|
|
||||||
ty::ImplContainer => wfcheck::impl_implied_bounds(
|
|
||||||
tcx,
|
|
||||||
param_env,
|
|
||||||
container_id.expect_local(),
|
|
||||||
impl_ty_span,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
let mut outlives_environment = OutlivesEnvironment::new(param_env);
|
let mut outlives_environment = OutlivesEnvironment::new(param_env);
|
||||||
outlives_environment.add_implied_bounds(&infcx, implied_bounds, impl_ty_hir_id);
|
outlives_environment.add_implied_bounds(&infcx, implied_bounds, impl_ty_hir_id);
|
||||||
infcx.check_region_obligations_and_report_errors(
|
infcx.check_region_obligations_and_report_errors(
|
||||||
|
|
|
@ -10,7 +10,6 @@ use rustc_hir::ItemKind;
|
||||||
use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
|
use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
|
||||||
use rustc_infer::infer::outlives::obligations::TypeOutlives;
|
use rustc_infer::infer::outlives::obligations::TypeOutlives;
|
||||||
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
|
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::Normalized;
|
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
|
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
|
||||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||||
|
@ -24,8 +23,6 @@ use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_trait_selection::autoderef::Autoderef;
|
use rustc_trait_selection::autoderef::Autoderef;
|
||||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::query::normalize::AtExt;
|
|
||||||
use rustc_trait_selection::traits::query::NoSolution;
|
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{
|
||||||
self, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
|
self, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
|
||||||
};
|
};
|
||||||
|
@ -86,18 +83,29 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
|
||||||
body_def_id: LocalDefId,
|
body_def_id: LocalDefId,
|
||||||
f: F,
|
f: F,
|
||||||
) where
|
) where
|
||||||
F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>) -> FxHashSet<Ty<'tcx>>,
|
F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>),
|
||||||
{
|
{
|
||||||
let param_env = tcx.param_env(body_def_id);
|
let param_env = tcx.param_env(body_def_id);
|
||||||
let body_id = tcx.hir().local_def_id_to_hir_id(body_def_id);
|
let body_id = tcx.hir().local_def_id_to_hir_id(body_def_id);
|
||||||
tcx.infer_ctxt().enter(|ref infcx| {
|
tcx.infer_ctxt().enter(|ref infcx| {
|
||||||
let ocx = ObligationCtxt::new(infcx);
|
let ocx = ObligationCtxt::new(infcx);
|
||||||
|
|
||||||
|
let assumed_wf_types = tcx.assumed_wf_types(body_def_id);
|
||||||
|
let mut implied_bounds = FxHashSet::default();
|
||||||
|
let cause = ObligationCause::misc(span, body_id);
|
||||||
|
for ty in assumed_wf_types {
|
||||||
|
implied_bounds.insert(ty);
|
||||||
|
let normalized = ocx.normalize(cause.clone(), param_env, ty);
|
||||||
|
implied_bounds.insert(normalized);
|
||||||
|
}
|
||||||
|
let implied_bounds = implied_bounds;
|
||||||
|
|
||||||
let mut wfcx = WfCheckingCtxt { ocx, span, body_id, param_env };
|
let mut wfcx = WfCheckingCtxt { ocx, span, body_id, param_env };
|
||||||
|
|
||||||
if !tcx.features().trivial_bounds {
|
if !tcx.features().trivial_bounds {
|
||||||
wfcx.check_false_global_bounds()
|
wfcx.check_false_global_bounds()
|
||||||
}
|
}
|
||||||
let wf_tys = f(&mut wfcx);
|
f(&mut wfcx);
|
||||||
let errors = wfcx.select_all_or_error();
|
let errors = wfcx.select_all_or_error();
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
infcx.report_fulfillment_errors(&errors, None, false);
|
infcx.report_fulfillment_errors(&errors, None, false);
|
||||||
|
@ -105,7 +113,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut outlives_environment = OutlivesEnvironment::new(param_env);
|
let mut outlives_environment = OutlivesEnvironment::new(param_env);
|
||||||
outlives_environment.add_implied_bounds(infcx, wf_tys, body_id);
|
outlives_environment.add_implied_bounds(infcx, implied_bounds, body_id);
|
||||||
infcx.check_region_obligations_and_report_errors(body_def_id, &outlives_environment);
|
infcx.check_region_obligations_and_report_errors(body_def_id, &outlives_environment);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -976,15 +984,9 @@ fn check_associated_item(
|
||||||
enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| {
|
enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| {
|
||||||
let item = tcx.associated_item(item_id);
|
let item = tcx.associated_item(item_id);
|
||||||
|
|
||||||
let (mut implied_bounds, self_ty) = match item.container {
|
let self_ty = match item.container {
|
||||||
ty::TraitContainer => (FxHashSet::default(), tcx.types.self_param),
|
ty::TraitContainer => tcx.types.self_param,
|
||||||
ty::ImplContainer => {
|
ty::ImplContainer => tcx.type_of(item.container_id(tcx)),
|
||||||
let def_id = item.container_id(tcx);
|
|
||||||
(
|
|
||||||
impl_implied_bounds(tcx, wfcx.param_env, def_id.expect_local(), span),
|
|
||||||
tcx.type_of(def_id),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match item.kind {
|
match item.kind {
|
||||||
|
@ -1002,7 +1004,6 @@ fn check_associated_item(
|
||||||
sig,
|
sig,
|
||||||
hir_sig.decl,
|
hir_sig.decl,
|
||||||
item.def_id.expect_local(),
|
item.def_id.expect_local(),
|
||||||
&mut implied_bounds,
|
|
||||||
);
|
);
|
||||||
check_method_receiver(wfcx, hir_sig, item, self_ty);
|
check_method_receiver(wfcx, hir_sig, item, self_ty);
|
||||||
}
|
}
|
||||||
|
@ -1017,8 +1018,6 @@ fn check_associated_item(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implied_bounds
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1118,9 +1117,6 @@ fn check_type_defn<'tcx, F>(
|
||||||
}
|
}
|
||||||
|
|
||||||
check_where_clauses(wfcx, item.span, item.def_id);
|
check_where_clauses(wfcx, item.span, item.def_id);
|
||||||
|
|
||||||
// No implied bounds in a struct definition.
|
|
||||||
FxHashSet::default()
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1144,9 +1140,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
enter_wf_checking_ctxt(tcx, item.span, item.def_id, |wfcx| {
|
enter_wf_checking_ctxt(tcx, item.span, item.def_id, |wfcx| {
|
||||||
check_where_clauses(wfcx, item.span, item.def_id);
|
check_where_clauses(wfcx, item.span, item.def_id)
|
||||||
|
|
||||||
FxHashSet::default()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only check traits, don't check trait aliases
|
// Only check traits, don't check trait aliases
|
||||||
|
@ -1186,9 +1180,7 @@ fn check_item_fn(
|
||||||
) {
|
) {
|
||||||
enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
|
enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
|
||||||
let sig = tcx.fn_sig(def_id);
|
let sig = tcx.fn_sig(def_id);
|
||||||
let mut implied_bounds = FxHashSet::default();
|
check_fn_or_method(wfcx, ident.span, sig, decl, def_id);
|
||||||
check_fn_or_method(wfcx, ident.span, sig, decl, def_id, &mut implied_bounds);
|
|
||||||
implied_bounds
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1231,9 +1223,6 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_fo
|
||||||
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
|
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No implied bounds in a const, etc.
|
|
||||||
FxHashSet::default()
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1284,8 +1273,6 @@ fn check_impl<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
check_where_clauses(wfcx, item.span, item.def_id);
|
check_where_clauses(wfcx, item.span, item.def_id);
|
||||||
|
|
||||||
impl_implied_bounds(tcx, wfcx.param_env, item.def_id, item.span)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1479,7 +1466,6 @@ fn check_fn_or_method<'tcx>(
|
||||||
sig: ty::PolyFnSig<'tcx>,
|
sig: ty::PolyFnSig<'tcx>,
|
||||||
hir_decl: &hir::FnDecl<'_>,
|
hir_decl: &hir::FnDecl<'_>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
implied_bounds: &mut FxHashSet<Ty<'tcx>>,
|
|
||||||
) {
|
) {
|
||||||
let tcx = wfcx.tcx();
|
let tcx = wfcx.tcx();
|
||||||
let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
|
let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
|
||||||
|
@ -1521,15 +1507,8 @@ fn check_fn_or_method<'tcx>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
implied_bounds.extend(sig.inputs());
|
|
||||||
|
|
||||||
wfcx.register_wf_obligation(hir_decl.output.span(), None, sig.output().into());
|
wfcx.register_wf_obligation(hir_decl.output.span(), None, sig.output().into());
|
||||||
|
|
||||||
// FIXME(#27579) return types should not be implied bounds
|
|
||||||
implied_bounds.insert(sig.output());
|
|
||||||
|
|
||||||
debug!(?implied_bounds);
|
|
||||||
|
|
||||||
check_where_clauses(wfcx, span, def_id);
|
check_where_clauses(wfcx, span, def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1924,40 +1903,6 @@ impl<'a, 'tcx> WfCheckingCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn impl_implied_bounds<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
impl_def_id: LocalDefId,
|
|
||||||
span: Span,
|
|
||||||
) -> FxHashSet<Ty<'tcx>> {
|
|
||||||
// We completely ignore any obligations caused by normalizing the types
|
|
||||||
// we assume to be well formed. Considering that the user of the implied
|
|
||||||
// bounds will also normalize them, we leave it to them to emit errors
|
|
||||||
// which should result in better causes and spans.
|
|
||||||
tcx.infer_ctxt().enter(|infcx| {
|
|
||||||
let cause = ObligationCause::misc(span, tcx.hir().local_def_id_to_hir_id(impl_def_id));
|
|
||||||
match tcx.impl_trait_ref(impl_def_id) {
|
|
||||||
Some(trait_ref) => {
|
|
||||||
// Trait impl: take implied bounds from all types that
|
|
||||||
// appear in the trait reference.
|
|
||||||
match infcx.at(&cause, param_env).normalize(trait_ref) {
|
|
||||||
Ok(Normalized { value, obligations: _ }) => value.substs.types().collect(),
|
|
||||||
Err(NoSolution) => FxHashSet::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None => {
|
|
||||||
// Inherent impl: take implied bounds from the `self` type.
|
|
||||||
let self_ty = tcx.type_of(impl_def_id);
|
|
||||||
match infcx.at(&cause, param_env).normalize(self_ty) {
|
|
||||||
Ok(Normalized { value, obligations: _ }) => FxHashSet::from_iter([value]),
|
|
||||||
Err(NoSolution) => FxHashSet::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn error_392(
|
fn error_392(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
|
@ -66,26 +66,25 @@
|
||||||
//! on traits with methods can.
|
//! on traits with methods can.
|
||||||
|
|
||||||
use crate::check::regionck::OutlivesEnvironmentExt;
|
use crate::check::regionck::OutlivesEnvironmentExt;
|
||||||
use crate::check::wfcheck::impl_implied_bounds;
|
|
||||||
use crate::constrained_generic_params as cgp;
|
use crate::constrained_generic_params as cgp;
|
||||||
use crate::errors::SubstsOnOverriddenImpl;
|
use crate::errors::SubstsOnOverriddenImpl;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::traits::specialization_graph::Node;
|
use rustc_infer::traits::specialization_graph::Node;
|
||||||
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
|
use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
|
||||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
|
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::{self, translate_substs, wf};
|
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
||||||
|
use rustc_trait_selection::traits::{self, translate_substs, wf, ObligationCtxt};
|
||||||
|
|
||||||
pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
|
pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
|
||||||
if let Some(node) = parent_specialization_node(tcx, impl_def_id) {
|
if let Some(node) = parent_specialization_node(tcx, impl_def_id) {
|
||||||
tcx.infer_ctxt().enter(|infcx| {
|
check_always_applicable(tcx, impl_def_id, node);
|
||||||
check_always_applicable(&infcx, impl_def_id, node);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,16 +104,14 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Opti
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that `impl1` is a sound specialization
|
/// Check that `impl1` is a sound specialization
|
||||||
fn check_always_applicable(infcx: &InferCtxt<'_, '_>, impl1_def_id: LocalDefId, impl2_node: Node) {
|
fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node) {
|
||||||
if let Some((impl1_substs, impl2_substs)) = get_impl_substs(infcx, impl1_def_id, impl2_node) {
|
if let Some((impl1_substs, impl2_substs)) = get_impl_substs(tcx, impl1_def_id, impl2_node) {
|
||||||
let impl2_def_id = impl2_node.def_id();
|
let impl2_def_id = impl2_node.def_id();
|
||||||
debug!(
|
debug!(
|
||||||
"check_always_applicable(\nimpl1_def_id={:?},\nimpl2_def_id={:?},\nimpl2_substs={:?}\n)",
|
"check_always_applicable(\nimpl1_def_id={:?},\nimpl2_def_id={:?},\nimpl2_substs={:?}\n)",
|
||||||
impl1_def_id, impl2_def_id, impl2_substs
|
impl1_def_id, impl2_def_id, impl2_substs
|
||||||
);
|
);
|
||||||
|
|
||||||
let tcx = infcx.tcx;
|
|
||||||
|
|
||||||
let parent_substs = if impl2_node.is_from_trait() {
|
let parent_substs = if impl2_node.is_from_trait() {
|
||||||
impl2_substs.to_vec()
|
impl2_substs.to_vec()
|
||||||
} else {
|
} else {
|
||||||
|
@ -124,7 +121,7 @@ fn check_always_applicable(infcx: &InferCtxt<'_, '_>, impl1_def_id: LocalDefId,
|
||||||
let span = tcx.def_span(impl1_def_id);
|
let span = tcx.def_span(impl1_def_id);
|
||||||
check_static_lifetimes(tcx, &parent_substs, span);
|
check_static_lifetimes(tcx, &parent_substs, span);
|
||||||
check_duplicate_params(tcx, impl1_substs, &parent_substs, span);
|
check_duplicate_params(tcx, impl1_substs, &parent_substs, span);
|
||||||
check_predicates(infcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);
|
check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,25 +136,37 @@ fn check_always_applicable(infcx: &InferCtxt<'_, '_>, impl1_def_id: LocalDefId,
|
||||||
///
|
///
|
||||||
/// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`.
|
/// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`.
|
||||||
fn get_impl_substs<'tcx>(
|
fn get_impl_substs<'tcx>(
|
||||||
infcx: &InferCtxt<'_, 'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl1_def_id: LocalDefId,
|
impl1_def_id: LocalDefId,
|
||||||
impl2_node: Node,
|
impl2_node: Node,
|
||||||
) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {
|
) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {
|
||||||
let tcx = infcx.tcx;
|
tcx.infer_ctxt().enter(|ref infcx| {
|
||||||
|
let ocx = ObligationCtxt::new(infcx);
|
||||||
let param_env = tcx.param_env(impl1_def_id);
|
let param_env = tcx.param_env(impl1_def_id);
|
||||||
|
let impl1_hir_id = tcx.hir().local_def_id_to_hir_id(impl1_def_id);
|
||||||
|
|
||||||
|
let assumed_wf_types = tcx.assumed_wf_types(impl1_def_id);
|
||||||
|
let mut implied_bounds = FxHashSet::default();
|
||||||
|
let cause = ObligationCause::misc(tcx.def_span(impl1_def_id), impl1_hir_id);
|
||||||
|
for ty in assumed_wf_types {
|
||||||
|
implied_bounds.insert(ty);
|
||||||
|
let normalized = ocx.normalize(cause.clone(), param_env, ty);
|
||||||
|
implied_bounds.insert(normalized);
|
||||||
|
}
|
||||||
|
let implied_bounds = implied_bounds;
|
||||||
|
|
||||||
let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id.to_def_id());
|
let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id.to_def_id());
|
||||||
let impl2_substs =
|
let impl2_substs =
|
||||||
translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node);
|
translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node);
|
||||||
|
|
||||||
|
let errors = ocx.select_all_or_error();
|
||||||
|
if !errors.is_empty() {
|
||||||
|
ocx.infcx.report_fulfillment_errors(&errors, None, false);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let mut outlives_env = OutlivesEnvironment::new(param_env);
|
let mut outlives_env = OutlivesEnvironment::new(param_env);
|
||||||
let implied_bounds =
|
outlives_env.add_implied_bounds(infcx, implied_bounds, impl1_hir_id);
|
||||||
impl_implied_bounds(infcx.tcx, param_env, impl1_def_id, tcx.def_span(impl1_def_id));
|
|
||||||
outlives_env.add_implied_bounds(
|
|
||||||
infcx,
|
|
||||||
implied_bounds,
|
|
||||||
tcx.hir().local_def_id_to_hir_id(impl1_def_id),
|
|
||||||
);
|
|
||||||
infcx.check_region_obligations_and_report_errors(impl1_def_id, &outlives_env);
|
infcx.check_region_obligations_and_report_errors(impl1_def_id, &outlives_env);
|
||||||
let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
|
let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
|
||||||
let span = tcx.def_span(impl1_def_id);
|
let span = tcx.def_span(impl1_def_id);
|
||||||
|
@ -165,6 +174,7 @@ fn get_impl_substs<'tcx>(
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
Some((impl1_substs, impl2_substs))
|
Some((impl1_substs, impl2_substs))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of all of the unconstrained subst of the given impl.
|
/// Returns a list of all of the unconstrained subst of the given impl.
|
||||||
|
@ -279,14 +289,13 @@ fn check_static_lifetimes<'tcx>(
|
||||||
/// * a well-formed predicate of a type argument of the trait being implemented,
|
/// * a well-formed predicate of a type argument of the trait being implemented,
|
||||||
/// including the `Self`-type.
|
/// including the `Self`-type.
|
||||||
fn check_predicates<'tcx>(
|
fn check_predicates<'tcx>(
|
||||||
infcx: &InferCtxt<'_, 'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl1_def_id: LocalDefId,
|
impl1_def_id: LocalDefId,
|
||||||
impl1_substs: SubstsRef<'tcx>,
|
impl1_substs: SubstsRef<'tcx>,
|
||||||
impl2_node: Node,
|
impl2_node: Node,
|
||||||
impl2_substs: SubstsRef<'tcx>,
|
impl2_substs: SubstsRef<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
let tcx = infcx.tcx;
|
|
||||||
let instantiated = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs);
|
let instantiated = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs);
|
||||||
let impl1_predicates: Vec<_> = traits::elaborate_predicates_with_span(
|
let impl1_predicates: Vec<_> = traits::elaborate_predicates_with_span(
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -343,19 +352,23 @@ fn check_predicates<'tcx>(
|
||||||
|
|
||||||
// Include the well-formed predicates of the type parameters of the impl.
|
// Include the well-formed predicates of the type parameters of the impl.
|
||||||
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().substs {
|
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().substs {
|
||||||
if let Some(obligations) = wf::obligations(
|
tcx.infer_ctxt().enter(|ref infcx| {
|
||||||
|
let obligations = wf::obligations(
|
||||||
infcx,
|
infcx,
|
||||||
tcx.param_env(impl1_def_id),
|
tcx.param_env(impl1_def_id),
|
||||||
tcx.hir().local_def_id_to_hir_id(impl1_def_id),
|
tcx.hir().local_def_id_to_hir_id(impl1_def_id),
|
||||||
0,
|
0,
|
||||||
arg,
|
arg,
|
||||||
span,
|
span,
|
||||||
) {
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert!(!obligations.needs_infer());
|
||||||
impl2_predicates.extend(
|
impl2_predicates.extend(
|
||||||
traits::elaborate_obligations(tcx, obligations)
|
traits::elaborate_obligations(tcx, obligations)
|
||||||
.map(|obligation| obligation.predicate),
|
.map(|obligation| obligation.predicate),
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
impl2_predicates.extend(
|
impl2_predicates.extend(
|
||||||
traits::elaborate_predicates_with_span(tcx, always_applicable_traits)
|
traits::elaborate_predicates_with_span(tcx, always_applicable_traits)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0277]: the trait bound `Self: Get` is not satisfied
|
error[E0277]: the trait bound `Self: Get` is not satisfied
|
||||||
--> $DIR/associated-types-for-unimpl-trait.rs:10:40
|
--> $DIR/associated-types-for-unimpl-trait.rs:10:5
|
||||||
|
|
|
|
||||||
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
||||||
|
|
|
|
||||||
help: consider further restricting `Self`
|
help: consider further restricting `Self`
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0277]: the trait bound `T: Get` is not satisfied
|
error[E0277]: the trait bound `T: Get` is not satisfied
|
||||||
--> $DIR/associated-types-no-suitable-bound.rs:11:21
|
--> $DIR/associated-types-no-suitable-bound.rs:11:5
|
||||||
|
|
|
|
||||||
LL | fn uhoh<T>(foo: <T as Get>::Value) {}
|
LL | fn uhoh<T>(foo: <T as Get>::Value) {}
|
||||||
| ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
|
||||||
|
|
|
|
||||||
help: consider restricting type parameter `T`
|
help: consider restricting type parameter `T`
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0277]: the trait bound `Self: Get` is not satisfied
|
error[E0277]: the trait bound `Self: Get` is not satisfied
|
||||||
--> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40
|
--> $DIR/associated-types-no-suitable-supertrait-2.rs:17:5
|
||||||
|
|
|
|
||||||
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
||||||
|
|
|
|
||||||
help: consider further restricting `Self`
|
help: consider further restricting `Self`
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
error[E0277]: the trait bound `(T, U): Get` is not satisfied
|
error[E0277]: the trait bound `(T, U): Get` is not satisfied
|
||||||
--> $DIR/associated-types-no-suitable-supertrait.rs:22:40
|
--> $DIR/associated-types-no-suitable-supertrait.rs:22:5
|
||||||
|
|
|
|
||||||
LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Self: Get` is not satisfied
|
error[E0277]: the trait bound `Self: Get` is not satisfied
|
||||||
--> $DIR/associated-types-no-suitable-supertrait.rs:17:40
|
--> $DIR/associated-types-no-suitable-supertrait.rs:17:5
|
||||||
|
|
|
|
||||||
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
||||||
|
|
|
|
||||||
help: consider further restricting `Self`
|
help: consider further restricting `Self`
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0277]: the trait bound `Self: Get` is not satisfied
|
error[E0277]: the trait bound `Self: Get` is not satisfied
|
||||||
--> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40
|
--> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:5
|
||||||
|
|
|
|
||||||
LL | fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
|
LL | fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
||||||
|
|
|
|
||||||
help: consider further restricting `Self`
|
help: consider further restricting `Self`
|
||||||
|
|
|
|
||||||
|
|
|
@ -45,16 +45,20 @@ LL | pub trait ThriftService<Bug: NotFoo + Foo>:
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
error[E0277]: the trait bound `(): Foo` is not satisfied
|
error[E0277]: the trait bound `(): Foo` is not satisfied
|
||||||
--> $DIR/issue-59324.rs:23:29
|
--> $DIR/issue-59324.rs:23:1
|
||||||
|
|
|
|
||||||
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
|
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Bug: Foo` is not satisfied
|
error[E0277]: the trait bound `Bug: Foo` is not satisfied
|
||||||
--> $DIR/issue-59324.rs:16:8
|
--> $DIR/issue-59324.rs:16:5
|
||||||
|
|
|
|
||||||
LL | fn get_service(
|
LL | / fn get_service(
|
||||||
| ^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug`
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | &self,
|
||||||
|
LL | | ) -> Self::AssocType;
|
||||||
|
| |_________________________^ the trait `Foo` is not implemented for `Bug`
|
||||||
|
|
|
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
error[E0277]: the trait bound `isize: HasState` is not satisfied
|
error[E0277]: the trait bound `isize: HasState` is not satisfied
|
||||||
--> $DIR/issue-18611.rs:1:18
|
--> $DIR/issue-18611.rs:1:1
|
||||||
|
|
|
|
||||||
LL | fn add_state(op: <isize as HasState>::State) {
|
LL | / fn add_state(op: <isize as HasState>::State) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize`
|
LL | |
|
||||||
|
LL | | }
|
||||||
|
| |_^ the trait `HasState` is not implemented for `isize`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
|
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
|
||||||
--> $DIR/issue-20831-debruijn.rs:28:8
|
--> $DIR/issue-20831-debruijn.rs:28:5
|
||||||
|
|
|
|
||||||
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
|
LL | / fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
|
||||||
| ^^^^^^^^^
|
LL | | // Not obvious, but there is an implicit lifetime here -------^
|
||||||
|
LL | |
|
||||||
|
LL | | //
|
||||||
|
... |
|
||||||
|
LL | | self.sub = t;
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
|
||||||
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
|
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
|
||||||
--> $DIR/issue-20831-debruijn.rs:28:58
|
--> $DIR/issue-20831-debruijn.rs:28:58
|
||||||
|
@ -15,10 +21,16 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he
|
||||||
LL | impl<'a> Publisher<'a> for MyStruct<'a> {
|
LL | impl<'a> Publisher<'a> for MyStruct<'a> {
|
||||||
| ^^
|
| ^^
|
||||||
note: ...so that the types are compatible
|
note: ...so that the types are compatible
|
||||||
--> $DIR/issue-20831-debruijn.rs:28:8
|
--> $DIR/issue-20831-debruijn.rs:28:5
|
||||||
|
|
|
|
||||||
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
|
LL | / fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
|
||||||
| ^^^^^^^^^
|
LL | | // Not obvious, but there is an implicit lifetime here -------^
|
||||||
|
LL | |
|
||||||
|
LL | | //
|
||||||
|
... |
|
||||||
|
LL | | self.sub = t;
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
= note: expected `<MyStruct<'a> as Publisher<'_>>`
|
= note: expected `<MyStruct<'a> as Publisher<'_>>`
|
||||||
found `<MyStruct<'_> as Publisher<'_>>`
|
found `<MyStruct<'_> as Publisher<'_>>`
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ trait Trait2<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
|
fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
|
||||||
//~^ the trait bound `for<'a> (): Trait2<'a>` is not satisfied
|
//~^ ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied
|
||||||
|
//~| ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied
|
||||||
let _e: (usize, usize) = unsafe{mem::transmute(param)};
|
let _e: (usize, usize) = unsafe{mem::transmute(param)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
|
error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
|
||||||
|
--> $DIR/issue-35570.rs:8:1
|
||||||
|
|
|
||||||
|
LL | / fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | let _e: (usize, usize) = unsafe{mem::transmute(param)};
|
||||||
|
LL | | }
|
||||||
|
| |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
|
||||||
|
|
||||||
error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
|
error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
|
||||||
--> $DIR/issue-35570.rs:8:40
|
--> $DIR/issue-35570.rs:8:40
|
||||||
|
|
|
|
||||||
LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
|
LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
|
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements
|
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements
|
||||||
--> $DIR/normalization-bounds-error.rs:12:4
|
--> $DIR/normalization-bounds-error.rs:12:1
|
||||||
|
|
|
|
||||||
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: first, the lifetime cannot outlive the lifetime `'d` as defined here...
|
note: first, the lifetime cannot outlive the lifetime `'d` as defined here...
|
||||||
--> $DIR/normalization-bounds-error.rs:12:14
|
--> $DIR/normalization-bounds-error.rs:12:14
|
||||||
|
@ -15,10 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he
|
||||||
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
|
||||||
| ^^
|
| ^^
|
||||||
note: ...so that the types are compatible
|
note: ...so that the types are compatible
|
||||||
--> $DIR/normalization-bounds-error.rs:12:4
|
--> $DIR/normalization-bounds-error.rs:12:1
|
||||||
|
|
|
|
||||||
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: expected `Visitor<'d>`
|
= note: expected `Visitor<'d>`
|
||||||
found `Visitor<'_>`
|
found `Visitor<'_>`
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ trait Trait2<'a, 'b> {
|
||||||
// since for it to be WF, we would need to know that `'y: 'x`, but we
|
// since for it to be WF, we would need to know that `'y: 'x`, but we
|
||||||
// do not infer that.
|
// do not infer that.
|
||||||
fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
|
fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
|
||||||
//~^ the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
|
//~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
|
||||||
|
//~| ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
|
||||||
|
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1
|
||||||
|
|
|
||||||
|
LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | {
|
||||||
|
LL | | }
|
||||||
|
| |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
|
||||||
|
|
|
||||||
|
help: consider restricting type parameter `T`
|
||||||
|
|
|
||||||
|
LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
|
||||||
|
| ++++++++++++++++++++++++
|
||||||
|
|
||||||
error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
|
error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
|
||||||
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49
|
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49
|
||||||
|
|
|
|
||||||
|
@ -9,6 +24,6 @@ help: consider restricting type parameter `T`
|
||||||
LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
|
LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
|
||||||
| ++++++++++++++++++++++++
|
| ++++++++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
error[E0277]: the trait bound `B: Clone` is not satisfied
|
error[E0277]: the trait bound `B: Clone` is not satisfied
|
||||||
--> $DIR/issue-79224.rs:18:17
|
--> $DIR/issue-79224.rs:18:1
|
||||||
|
|
|
|
||||||
LL | impl<B: ?Sized> Display for Cow<'_, B> {
|
LL | / impl<B: ?Sized> Display for Cow<'_, B> {
|
||||||
| ^^^^^^^ the trait `Clone` is not implemented for `B`
|
LL | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
LL | | write!(f, "foo")
|
||||||
|
LL | | }
|
||||||
|
LL | | }
|
||||||
|
| |_^ the trait `Clone` is not implemented for `B`
|
||||||
|
|
|
|
||||||
= note: required because of the requirements on the impl of `ToOwned` for `B`
|
= note: required because of the requirements on the impl of `ToOwned` for `B`
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
@ -11,10 +15,12 @@ LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
|
||||||
| +++++++++++++++++++
|
| +++++++++++++++++++
|
||||||
|
|
||||||
error[E0277]: the trait bound `B: Clone` is not satisfied
|
error[E0277]: the trait bound `B: Clone` is not satisfied
|
||||||
--> $DIR/issue-79224.rs:19:12
|
--> $DIR/issue-79224.rs:19:5
|
||||||
|
|
|
|
||||||
LL | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
LL | / fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
| ^^^^^ the trait `Clone` is not implemented for `B`
|
LL | | write!(f, "foo")
|
||||||
|
LL | | }
|
||||||
|
| |_____^ the trait `Clone` is not implemented for `B`
|
||||||
|
|
|
|
||||||
= note: required because of the requirements on the impl of `ToOwned` for `B`
|
= note: required because of the requirements on the impl of `ToOwned` for `B`
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0277]: the trait bound `Foo: HasComponent<()>` is not satisfied
|
error[E0277]: the trait bound `Foo: HasComponent<()>` is not satisfied
|
||||||
--> $DIR/issue-91594.rs:10:6
|
--> $DIR/issue-91594.rs:10:1
|
||||||
|
|
|
|
||||||
LL | impl HasComponent<<Foo as Component<Foo>>::Interface> for Foo {}
|
LL | impl HasComponent<<Foo as Component<Foo>>::Interface> for Foo {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
|
||||||
|
|
|
|
||||||
= help: the trait `HasComponent<<Foo as Component<Foo>>::Interface>` is implemented for `Foo`
|
= help: the trait `HasComponent<<Foo as Component<Foo>>::Interface>` is implemented for `Foo`
|
||||||
note: required because of the requirements on the impl of `Component<Foo>` for `Foo`
|
note: required because of the requirements on the impl of `Component<Foo>` for `Foo`
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0277]: the trait bound `(): Foo` is not satisfied
|
error[E0277]: the trait bound `(): Foo` is not satisfied
|
||||||
--> $DIR/wf-foreign-fn-decl-ret.rs:11:25
|
--> $DIR/wf-foreign-fn-decl-ret.rs:11:5
|
||||||
|
|
|
|
||||||
LL | pub fn lint_me() -> <() as Foo>::Assoc;
|
LL | pub fn lint_me() -> <() as Foo>::Assoc;
|
||||||
| ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
|
||||||
|
|
||||||
error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied
|
error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied
|
||||||
--> $DIR/wf-foreign-fn-decl-ret.rs:14:32
|
--> $DIR/wf-foreign-fn-decl-ret.rs:14:32
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue