mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Auto merge of #104758 - Manishearth:rollup-rh1tfum, r=Manishearth
Rollup of 6 pull requests Successful merges: - #103488 (Allow opaque types in trait impl headers and rely on coherence to reject unsound cases) - #104359 (Refactor must_use lint into two parts) - #104612 (Lower return type outside async block creation) - #104621 (Fix --extern library finding errors) - #104647 (enable fuzzy_provenance_casts lint in liballoc and libstd) - #104750 (Bump `fd-lock` in `bootstrap` again) Failed merges: - #104732 (Refactor `ty::ClosureKind` related stuff) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
3f2b2eee8f
@ -588,17 +588,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
capture_clause: CaptureBy,
|
capture_clause: CaptureBy,
|
||||||
closure_node_id: NodeId,
|
closure_node_id: NodeId,
|
||||||
ret_ty: Option<AstP<Ty>>,
|
ret_ty: Option<hir::FnRetTy<'hir>>,
|
||||||
span: Span,
|
span: Span,
|
||||||
async_gen_kind: hir::AsyncGeneratorKind,
|
async_gen_kind: hir::AsyncGeneratorKind,
|
||||||
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
|
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
|
||||||
) -> hir::ExprKind<'hir> {
|
) -> hir::ExprKind<'hir> {
|
||||||
let output = match ret_ty {
|
let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));
|
||||||
Some(ty) => hir::FnRetTy::Return(
|
|
||||||
self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)),
|
|
||||||
),
|
|
||||||
None => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Resume argument type. We let the compiler infer this to simplify the lowering. It is
|
// Resume argument type. We let the compiler infer this to simplify the lowering. It is
|
||||||
// fully constrained by `future::from_generator`.
|
// fully constrained by `future::from_generator`.
|
||||||
@ -1003,8 +998,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
// Transform `async |x: u8| -> X { ... }` into
|
// Transform `async |x: u8| -> X { ... }` into
|
||||||
// `|x: u8| future_from_generator(|| -> X { ... })`.
|
// `|x: u8| future_from_generator(|| -> X { ... })`.
|
||||||
let body_id = this.lower_fn_body(&outer_decl, |this| {
|
let body_id = this.lower_fn_body(&outer_decl, |this| {
|
||||||
let async_ret_ty =
|
let async_ret_ty = if let FnRetTy::Ty(ty) = &decl.output {
|
||||||
if let FnRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None };
|
let itctx = ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock);
|
||||||
|
Some(hir::FnRetTy::Return(this.lower_ty(&ty, &itctx)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let async_body = this.make_async_expr(
|
let async_body = this.make_async_expr(
|
||||||
capture_clause,
|
capture_clause,
|
||||||
inner_closure_id,
|
inner_closure_id,
|
||||||
|
@ -2,9 +2,8 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRe
|
|||||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||||
use rustc_infer::traits::PredicateObligations;
|
use rustc_infer::traits::PredicateObligations;
|
||||||
use rustc_middle::mir::ConstraintCategory;
|
use rustc_middle::mir::ConstraintCategory;
|
||||||
use rustc_middle::ty::error::TypeError;
|
|
||||||
use rustc_middle::ty::relate::TypeRelation;
|
use rustc_middle::ty::relate::TypeRelation;
|
||||||
use rustc_middle::ty::{self, Const, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::query::Fallible;
|
use rustc_trait_selection::traits::query::Fallible;
|
||||||
|
|
||||||
@ -141,13 +140,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't have to worry about the equality of consts during borrow checking
|
|
||||||
// as consts always have a static lifetime.
|
|
||||||
// FIXME(oli-obk): is this really true? We can at least have HKL and with
|
|
||||||
// inline consts we may have further lifetimes that may be unsound to treat as
|
|
||||||
// 'static.
|
|
||||||
fn const_equate(&mut self, _a: Const<'tcx>, _b: Const<'tcx>) {}
|
|
||||||
|
|
||||||
fn normalization() -> NormalizationStrategy {
|
fn normalization() -> NormalizationStrategy {
|
||||||
NormalizationStrategy::Eager
|
NormalizationStrategy::Eager
|
||||||
}
|
}
|
||||||
@ -156,10 +148,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_opaque_type_obligations(
|
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
||||||
&mut self,
|
|
||||||
obligations: PredicateObligations<'tcx>,
|
|
||||||
) -> Result<(), TypeError<'tcx>> {
|
|
||||||
self.type_checker
|
self.type_checker
|
||||||
.fully_perform_op(
|
.fully_perform_op(
|
||||||
self.locations,
|
self.locations,
|
||||||
@ -172,6 +161,5 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ metadata_crate_location_unknown_type =
|
|||||||
extern location for {$crate_name} is of an unknown type: {$path}
|
extern location for {$crate_name} is of an unknown type: {$path}
|
||||||
|
|
||||||
metadata_lib_filename_form =
|
metadata_lib_filename_form =
|
||||||
file name should be lib*.rlib or {dll_prefix}*.{dll_suffix}
|
file name should be lib*.rlib or {$dll_prefix}*{$dll_suffix}
|
||||||
|
|
||||||
metadata_multiple_import_name_type =
|
metadata_multiple_import_name_type =
|
||||||
multiple `import_name_type` arguments in a single `#[link]` attribute
|
multiple `import_name_type` arguments in a single `#[link]` attribute
|
||||||
|
@ -244,6 +244,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
|
|||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.param_env
|
self.param_env
|
||||||
}
|
}
|
||||||
@ -256,6 +260,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
bug!()
|
||||||
|
}
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: ty::Variance,
|
_: ty::Variance,
|
||||||
|
@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashSet;
|
|||||||
use rustc_errors::{struct_span_err, DelayDm};
|
use rustc_errors::{struct_span_err, DelayDm};
|
||||||
use rustc_errors::{Diagnostic, ErrorGuaranteed};
|
use rustc_errors::{Diagnostic, ErrorGuaranteed};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::ty::subst::GenericArgKind;
|
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
use rustc_middle::ty::subst::InternalSubsts;
|
||||||
use rustc_middle::ty::util::IgnoreRegions;
|
use rustc_middle::ty::util::IgnoreRegions;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
@ -47,58 +46,6 @@ fn do_orphan_check_impl<'tcx>(
|
|||||||
let sp = tcx.def_span(def_id);
|
let sp = tcx.def_span(def_id);
|
||||||
let tr = impl_.of_trait.as_ref().unwrap();
|
let tr = impl_.of_trait.as_ref().unwrap();
|
||||||
|
|
||||||
// Ensure no opaque types are present in this impl header. See issues #76202 and #86411 for examples,
|
|
||||||
// and #84660 where it would otherwise allow unsoundness.
|
|
||||||
if trait_ref.has_opaque_types() {
|
|
||||||
trace!("{:#?}", item);
|
|
||||||
// First we find the opaque type in question.
|
|
||||||
for ty in trait_ref.substs {
|
|
||||||
for ty in ty.walk() {
|
|
||||||
let ty::subst::GenericArgKind::Type(ty) = ty.unpack() else { continue };
|
|
||||||
let ty::Opaque(def_id, _) = *ty.kind() else { continue };
|
|
||||||
trace!(?def_id);
|
|
||||||
|
|
||||||
// Then we search for mentions of the opaque type's type alias in the HIR
|
|
||||||
struct SpanFinder<'tcx> {
|
|
||||||
sp: Span,
|
|
||||||
def_id: DefId,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
}
|
|
||||||
impl<'v, 'tcx> hir::intravisit::Visitor<'v> for SpanFinder<'tcx> {
|
|
||||||
#[instrument(level = "trace", skip(self, _id))]
|
|
||||||
fn visit_path(&mut self, path: &'v hir::Path<'v>, _id: hir::HirId) {
|
|
||||||
// You can't mention an opaque type directly, so we look for type aliases
|
|
||||||
if let hir::def::Res::Def(hir::def::DefKind::TyAlias, def_id) = path.res {
|
|
||||||
// And check if that type alias's type contains the opaque type we're looking for
|
|
||||||
for arg in self.tcx.type_of(def_id).walk() {
|
|
||||||
if let GenericArgKind::Type(ty) = arg.unpack() {
|
|
||||||
if let ty::Opaque(def_id, _) = *ty.kind() {
|
|
||||||
if def_id == self.def_id {
|
|
||||||
// Finally we update the span to the mention of the type alias
|
|
||||||
self.sp = path.span;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::intravisit::walk_path(self, path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut visitor = SpanFinder { sp, def_id, tcx };
|
|
||||||
hir::intravisit::walk_item(&mut visitor, item);
|
|
||||||
let reported = tcx
|
|
||||||
.sess
|
|
||||||
.struct_span_err(visitor.sp, "cannot implement trait on type alias impl trait")
|
|
||||||
.span_note(tcx.def_span(def_id), "type alias impl trait defined here")
|
|
||||||
.emit();
|
|
||||||
return Err(reported);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
span_bug!(sp, "opaque type not found, but `has_opaque_types` is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
match traits::orphan_check(tcx, item.owner_id.to_def_id()) {
|
match traits::orphan_check(tcx, item.owner_id.to_def_id()) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(err) => emit_orphan_check_error(
|
Err(err) => emit_orphan_check_error(
|
||||||
|
@ -517,6 +517,7 @@ fn trait_predicate_kind<'tcx>(
|
|||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
|||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -702,6 +702,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// code is looking for a self type of an unresolved
|
// code is looking for a self type of an unresolved
|
||||||
// inference variable.
|
// inference variable.
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -803,6 +803,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
| ty::PredicateKind::TypeOutlives(..)
|
| ty::PredicateKind::TypeOutlives(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -81,6 +81,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
.normalize_fn_sig_for_diagnostic
|
.normalize_fn_sig_for_diagnostic
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|f| f.clone()),
|
.map(|f| f.clone()),
|
||||||
|
intercrate: self.intercrate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,10 @@ use rustc_index::vec::Idx;
|
|||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_middle::arena::ArenaAllocatable;
|
use rustc_middle::arena::ArenaAllocatable;
|
||||||
use rustc_middle::mir::ConstraintCategory;
|
use rustc_middle::mir::ConstraintCategory;
|
||||||
use rustc_middle::ty::error::TypeError;
|
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::relate::TypeRelation;
|
use rustc_middle::ty::relate::TypeRelation;
|
||||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
|
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
|
||||||
use rustc_middle::ty::{self, BoundVar, Const, ToPredicate, Ty, TyCtxt};
|
use rustc_middle::ty::{self, BoundVar, ToPredicate, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
@ -729,10 +728,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn const_equate(&mut self, _a: Const<'tcx>, _b: Const<'tcx>) {
|
|
||||||
span_bug!(self.cause.span(), "generic_const_exprs: unreachable `const_equate`");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn normalization() -> NormalizationStrategy {
|
fn normalization() -> NormalizationStrategy {
|
||||||
NormalizationStrategy::Eager
|
NormalizationStrategy::Eager
|
||||||
}
|
}
|
||||||
@ -741,11 +736,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_opaque_type_obligations(
|
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
||||||
&mut self,
|
|
||||||
obligations: PredicateObligations<'tcx>,
|
|
||||||
) -> Result<(), TypeError<'tcx>> {
|
|
||||||
self.obligations.extend(obligations);
|
self.obligations.extend(obligations);
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -450,6 +450,15 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
|
|||||||
ty::Binder::dummy(predicate),
|
ty::Binder::dummy(predicate),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mark_ambiguous(&mut self) {
|
||||||
|
self.obligations.push(Obligation::new(
|
||||||
|
self.tcx(),
|
||||||
|
self.trace.cause.clone(),
|
||||||
|
self.param_env,
|
||||||
|
ty::Binder::dummy(ty::PredicateKind::Ambiguous),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Generalizer<'cx, 'tcx> {
|
struct Generalizer<'cx, 'tcx> {
|
||||||
@ -521,6 +530,11 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
self.infcx.intercrate
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.param_env
|
self.param_env
|
||||||
}
|
}
|
||||||
@ -533,6 +547,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
span_bug!(self.cause.span, "opaque types are handled in `tys`");
|
||||||
|
}
|
||||||
|
|
||||||
fn binders<T>(
|
fn binders<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
a: ty::Binder<'tcx, T>,
|
a: ty::Binder<'tcx, T>,
|
||||||
@ -657,6 +675,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||||||
// relatable.
|
// relatable.
|
||||||
Ok(t)
|
Ok(t)
|
||||||
}
|
}
|
||||||
|
ty::Opaque(def_id, substs) => {
|
||||||
|
let s = self.relate(substs, substs)?;
|
||||||
|
Ok(if s == substs { t } else { self.infcx.tcx.mk_opaque(def_id, s) })
|
||||||
|
}
|
||||||
_ => relate::super_relate_tys(self, t, t),
|
_ => relate::super_relate_tys(self, t, t),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
@ -799,6 +821,11 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
|
|||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
assert!(!self.infcx.intercrate);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.param_env
|
self.param_env
|
||||||
}
|
}
|
||||||
@ -811,6 +838,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
bug!()
|
||||||
|
}
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_variance: ty::Variance,
|
_variance: ty::Variance,
|
||||||
|
@ -32,6 +32,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
|
|||||||
self.fields.tcx()
|
self.fields.tcx()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
self.fields.infcx.intercrate
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.fields.param_env
|
self.fields.param_env
|
||||||
}
|
}
|
||||||
@ -40,6 +44,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
|
|||||||
self.a_is_expected
|
self.a_is_expected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
self.fields.mark_ambiguous();
|
||||||
|
}
|
||||||
|
|
||||||
fn relate_item_substs(
|
fn relate_item_substs(
|
||||||
&mut self,
|
&mut self,
|
||||||
_item_def_id: DefId,
|
_item_def_id: DefId,
|
||||||
|
@ -2937,6 +2937,11 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
|
|||||||
self.0.tcx
|
self.0.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
assert!(!self.0.intercrate);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
// Unused, only for consts which we treat as always equal
|
// Unused, only for consts which we treat as always equal
|
||||||
ty::ParamEnv::empty()
|
ty::ParamEnv::empty()
|
||||||
@ -2950,6 +2955,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
bug!()
|
||||||
|
}
|
||||||
|
|
||||||
fn relate_with_variance<T: relate::Relate<'tcx>>(
|
fn relate_with_variance<T: relate::Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_variance: ty::Variance,
|
_variance: ty::Variance,
|
||||||
|
@ -30,6 +30,11 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
|
|||||||
"Glb"
|
"Glb"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
assert!(!self.fields.infcx.intercrate);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.fields.tcx()
|
self.fields.tcx()
|
||||||
}
|
}
|
||||||
@ -42,6 +47,10 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
|
|||||||
self.a_is_expected
|
self.a_is_expected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
bug!("mark_ambiguous used outside of coherence");
|
||||||
|
}
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
variance: ty::Variance,
|
variance: ty::Variance,
|
||||||
|
@ -30,6 +30,11 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
|
|||||||
"Lub"
|
"Lub"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
assert!(!self.fields.infcx.intercrate);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.fields.tcx()
|
self.fields.tcx()
|
||||||
}
|
}
|
||||||
@ -42,6 +47,10 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
|
|||||||
self.a_is_expected
|
self.a_is_expected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
bug!("mark_ambiguous used outside of coherence");
|
||||||
|
}
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
variance: ty::Variance,
|
variance: ty::Variance,
|
||||||
|
@ -337,6 +337,26 @@ pub struct InferCtxt<'tcx> {
|
|||||||
|
|
||||||
normalize_fn_sig_for_diagnostic:
|
normalize_fn_sig_for_diagnostic:
|
||||||
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
|
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
|
||||||
|
|
||||||
|
/// During coherence we have to assume that other crates may add
|
||||||
|
/// additional impls which we currently don't know about.
|
||||||
|
///
|
||||||
|
/// To deal with this evaluation should be conservative
|
||||||
|
/// and consider the possibility of impls from outside this crate.
|
||||||
|
/// This comes up primarily when resolving ambiguity. Imagine
|
||||||
|
/// there is some trait reference `$0: Bar` where `$0` is an
|
||||||
|
/// inference variable. If `intercrate` is true, then we can never
|
||||||
|
/// say for sure that this reference is not implemented, even if
|
||||||
|
/// there are *no impls at all for `Bar`*, because `$0` could be
|
||||||
|
/// bound to some type that in a downstream crate that implements
|
||||||
|
/// `Bar`.
|
||||||
|
///
|
||||||
|
/// Outside of coherence we set this to false because we are only
|
||||||
|
/// interested in types that the user could actually have written.
|
||||||
|
/// In other words, we consider `$0: Bar` to be unimplemented if
|
||||||
|
/// there is no type that the user could *actually name* that
|
||||||
|
/// would satisfy it. This avoids crippling inference, basically.
|
||||||
|
pub intercrate: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See the `error_reporting` module for more details.
|
/// See the `error_reporting` module for more details.
|
||||||
@ -552,6 +572,8 @@ pub struct InferCtxtBuilder<'tcx> {
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
defining_use_anchor: DefiningAnchor,
|
defining_use_anchor: DefiningAnchor,
|
||||||
considering_regions: bool,
|
considering_regions: bool,
|
||||||
|
/// Whether we are in coherence mode.
|
||||||
|
intercrate: bool,
|
||||||
normalize_fn_sig_for_diagnostic:
|
normalize_fn_sig_for_diagnostic:
|
||||||
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
|
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
|
||||||
}
|
}
|
||||||
@ -567,6 +589,7 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
|
|||||||
defining_use_anchor: DefiningAnchor::Error,
|
defining_use_anchor: DefiningAnchor::Error,
|
||||||
considering_regions: true,
|
considering_regions: true,
|
||||||
normalize_fn_sig_for_diagnostic: None,
|
normalize_fn_sig_for_diagnostic: None,
|
||||||
|
intercrate: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -583,6 +606,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn intercrate(mut self) -> Self {
|
||||||
|
self.intercrate = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ignoring_regions(mut self) -> Self {
|
pub fn ignoring_regions(mut self) -> Self {
|
||||||
self.considering_regions = false;
|
self.considering_regions = false;
|
||||||
self
|
self
|
||||||
@ -622,6 +650,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
|||||||
defining_use_anchor,
|
defining_use_anchor,
|
||||||
considering_regions,
|
considering_regions,
|
||||||
ref normalize_fn_sig_for_diagnostic,
|
ref normalize_fn_sig_for_diagnostic,
|
||||||
|
intercrate,
|
||||||
} = *self;
|
} = *self;
|
||||||
InferCtxt {
|
InferCtxt {
|
||||||
tcx,
|
tcx,
|
||||||
@ -641,6 +670,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
|||||||
normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
|
normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|f| f.clone()),
|
.map(|f| f.clone()),
|
||||||
|
intercrate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ use crate::infer::combine::ConstEquateRelation;
|
|||||||
use crate::infer::InferCtxt;
|
use crate::infer::InferCtxt;
|
||||||
use crate::infer::{ConstVarValue, ConstVariableValue};
|
use crate::infer::{ConstVarValue, ConstVariableValue};
|
||||||
use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
|
use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use crate::traits::PredicateObligation;
|
use crate::traits::{Obligation, PredicateObligation};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty::error::TypeError;
|
use rustc_middle::ty::error::TypeError;
|
||||||
@ -92,11 +92,7 @@ pub trait TypeRelatingDelegate<'tcx> {
|
|||||||
info: ty::VarianceDiagInfo<'tcx>,
|
info: ty::VarianceDiagInfo<'tcx>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
|
fn register_obligations(&mut self, obligations: Vec<PredicateObligation<'tcx>>);
|
||||||
fn register_opaque_type_obligations(
|
|
||||||
&mut self,
|
|
||||||
obligations: Vec<PredicateObligation<'tcx>>,
|
|
||||||
) -> Result<(), TypeError<'tcx>>;
|
|
||||||
|
|
||||||
/// Creates a new universe index. Used when instantiating placeholders.
|
/// Creates a new universe index. Used when instantiating placeholders.
|
||||||
fn create_next_universe(&mut self) -> ty::UniverseIndex;
|
fn create_next_universe(&mut self) -> ty::UniverseIndex;
|
||||||
@ -419,7 +415,7 @@ where
|
|||||||
.infcx
|
.infcx
|
||||||
.handle_opaque_type(a, b, true, &cause, self.delegate.param_env())?
|
.handle_opaque_type(a, b, true, &cause, self.delegate.param_env())?
|
||||||
.obligations;
|
.obligations;
|
||||||
self.delegate.register_opaque_type_obligations(obligations)?;
|
self.delegate.register_obligations(obligations);
|
||||||
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
|
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}
|
}
|
||||||
@ -531,6 +527,10 @@ where
|
|||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
self.infcx.intercrate
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.delegate.param_env()
|
self.delegate.param_env()
|
||||||
}
|
}
|
||||||
@ -543,6 +543,17 @@ where
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
let cause = ObligationCause::dummy_with_span(self.delegate.span());
|
||||||
|
let param_env = self.delegate.param_env();
|
||||||
|
self.delegate.register_obligations(vec![Obligation::new(
|
||||||
|
self.tcx(),
|
||||||
|
cause,
|
||||||
|
param_env,
|
||||||
|
ty::Binder::dummy(ty::PredicateKind::Ambiguous),
|
||||||
|
)]);
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(skip(self, info), level = "trace", ret)]
|
#[instrument(skip(self, info), level = "trace", ret)]
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -800,8 +811,12 @@ impl<'tcx, D> ConstEquateRelation<'tcx> for TypeRelating<'_, 'tcx, D>
|
|||||||
where
|
where
|
||||||
D: TypeRelatingDelegate<'tcx>,
|
D: TypeRelatingDelegate<'tcx>,
|
||||||
{
|
{
|
||||||
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
|
fn const_equate_obligation(&mut self, _a: ty::Const<'tcx>, _b: ty::Const<'tcx>) {
|
||||||
self.delegate.const_equate(a, b);
|
// We don't have to worry about the equality of consts during borrow checking
|
||||||
|
// as consts always have a static lifetime.
|
||||||
|
// FIXME(oli-obk): is this really true? We can at least have HKL and with
|
||||||
|
// inline consts we may have further lifetimes that may be unsound to treat as
|
||||||
|
// 'static.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -898,6 +913,11 @@ where
|
|||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
assert!(!self.infcx.intercrate);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.delegate.param_env()
|
self.delegate.param_env()
|
||||||
}
|
}
|
||||||
@ -910,6 +930,10 @@ where
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
bug!()
|
||||||
|
}
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
variance: ty::Variance,
|
variance: ty::Variance,
|
||||||
|
@ -29,6 +29,7 @@ pub fn explicit_outlives_bounds<'tcx>(
|
|||||||
| ty::PredicateKind::TypeOutlives(..)
|
| ty::PredicateKind::TypeOutlives(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
|
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
|
||||||
Some(OutlivesBound::RegionSubRegion(r_b, r_a))
|
Some(OutlivesBound::RegionSubRegion(r_b, r_a))
|
||||||
|
@ -136,6 +136,11 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
|
|||||||
fn tag(&self) -> &'static str {
|
fn tag(&self) -> &'static str {
|
||||||
"Match"
|
"Match"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
@ -146,6 +151,10 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
|
|||||||
true
|
true
|
||||||
} // irrelevant
|
} // irrelevant
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
bug!()
|
||||||
|
}
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: ty::Variance,
|
_: ty::Variance,
|
||||||
|
@ -35,6 +35,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
|||||||
fn tag(&self) -> &'static str {
|
fn tag(&self) -> &'static str {
|
||||||
"Sub"
|
"Sub"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
self.fields.infcx.intercrate
|
||||||
|
}
|
||||||
|
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.fields.infcx.tcx
|
self.fields.infcx.tcx
|
||||||
}
|
}
|
||||||
@ -47,6 +52,10 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
|||||||
self.a_is_expected
|
self.a_is_expected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
self.fields.mark_ambiguous()
|
||||||
|
}
|
||||||
|
|
||||||
fn with_cause<F, R>(&mut self, cause: Cause, f: F) -> R
|
fn with_cause<F, R>(&mut self, cause: Cause, f: F) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> R,
|
F: FnOnce(&mut Self) -> R,
|
||||||
|
@ -285,6 +285,7 @@ impl<'tcx> Elaborator<'tcx> {
|
|||||||
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
// Nothing to elaborate
|
// Nothing to elaborate
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Ambiguous => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1659,6 +1659,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
|||||||
Coerce(..) |
|
Coerce(..) |
|
||||||
ConstEvaluatable(..) |
|
ConstEvaluatable(..) |
|
||||||
ConstEquate(..) |
|
ConstEquate(..) |
|
||||||
|
Ambiguous |
|
||||||
TypeWellFormedFromEnv(..) => continue,
|
TypeWellFormedFromEnv(..) => continue,
|
||||||
};
|
};
|
||||||
if predicate.is_global() {
|
if predicate.is_global() {
|
||||||
|
@ -13,6 +13,7 @@ use rustc_middle::ty::{self, DefIdTree, Ty};
|
|||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_span::symbol::{kw, sym};
|
use rustc_span::symbol::{kw, sym};
|
||||||
use rustc_span::{BytePos, Span};
|
use rustc_span::{BytePos, Span};
|
||||||
|
use std::iter;
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `unused_must_use` lint detects unused result of a type flagged as
|
/// The `unused_must_use` lint detects unused result of a type flagged as
|
||||||
@ -113,30 +114,19 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let ty = cx.typeck_results().expr_ty(&expr);
|
let ty = cx.typeck_results().expr_ty(&expr);
|
||||||
let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, expr.span, "", "", 1);
|
|
||||||
|
|
||||||
let mut fn_warned = false;
|
let must_use_result = is_ty_must_use(cx, ty, &expr, expr.span);
|
||||||
let mut op_warned = false;
|
let type_lint_emitted_or_suppressed = match must_use_result {
|
||||||
let maybe_def_id = match expr.kind {
|
Some(path) => {
|
||||||
hir::ExprKind::Call(ref callee, _) => {
|
emit_must_use_untranslated(cx, &path, "", "", 1);
|
||||||
match callee.kind {
|
true
|
||||||
hir::ExprKind::Path(ref qpath) => {
|
|
||||||
match cx.qpath_res(qpath, callee.hir_id) {
|
|
||||||
Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => Some(def_id),
|
|
||||||
// `Res::Local` if it was a closure, for which we
|
|
||||||
// do not currently support must-use linting
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
hir::ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id),
|
None => false,
|
||||||
_ => None,
|
|
||||||
};
|
};
|
||||||
if let Some(def_id) = maybe_def_id {
|
|
||||||
fn_warned = check_must_use_def(cx, def_id, expr.span, "return value of ", "");
|
let fn_warned = check_fn_must_use(cx, expr);
|
||||||
} else if type_permits_lack_of_use {
|
|
||||||
|
if !fn_warned && type_lint_emitted_or_suppressed {
|
||||||
// We don't warn about unused unit or uninhabited types.
|
// We don't warn about unused unit or uninhabited types.
|
||||||
// (See https://github.com/rust-lang/rust/issues/43806 for details.)
|
// (See https://github.com/rust-lang/rust/issues/43806 for details.)
|
||||||
return;
|
return;
|
||||||
@ -170,6 +160,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut op_warned = false;
|
||||||
|
|
||||||
if let Some(must_use_op) = must_use_op {
|
if let Some(must_use_op) = must_use_op {
|
||||||
cx.struct_span_lint(UNUSED_MUST_USE, expr.span, fluent::lint_unused_op, |lint| {
|
cx.struct_span_lint(UNUSED_MUST_USE, expr.span, fluent::lint_unused_op, |lint| {
|
||||||
lint.set_arg("op", must_use_op)
|
lint.set_arg("op", must_use_op)
|
||||||
@ -184,22 +176,64 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||||||
op_warned = true;
|
op_warned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(type_permits_lack_of_use || fn_warned || op_warned) {
|
if !(type_lint_emitted_or_suppressed || fn_warned || op_warned) {
|
||||||
cx.struct_span_lint(UNUSED_RESULTS, s.span, fluent::lint_unused_result, |lint| {
|
cx.struct_span_lint(UNUSED_RESULTS, s.span, fluent::lint_unused_result, |lint| {
|
||||||
lint.set_arg("ty", ty)
|
lint.set_arg("ty", ty)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether an error has been emitted (and thus another does not need to be later).
|
fn check_fn_must_use(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
||||||
fn check_must_use_ty<'tcx>(
|
let maybe_def_id = match expr.kind {
|
||||||
|
hir::ExprKind::Call(ref callee, _) => {
|
||||||
|
match callee.kind {
|
||||||
|
hir::ExprKind::Path(ref qpath) => {
|
||||||
|
match cx.qpath_res(qpath, callee.hir_id) {
|
||||||
|
Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => Some(def_id),
|
||||||
|
// `Res::Local` if it was a closure, for which we
|
||||||
|
// do not currently support must-use linting
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hir::ExprKind::MethodCall(..) => {
|
||||||
|
cx.typeck_results().type_dependent_def_id(expr.hir_id)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if let Some(def_id) = maybe_def_id {
|
||||||
|
check_must_use_def(cx, def_id, expr.span, "return value of ", "")
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A path through a type to a must_use source. Contains useful info for the lint.
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum MustUsePath {
|
||||||
|
/// Suppress must_use checking.
|
||||||
|
Suppressed,
|
||||||
|
/// The root of the normal must_use lint with an optional message.
|
||||||
|
Def(Span, DefId, Option<Symbol>),
|
||||||
|
Boxed(Box<Self>),
|
||||||
|
Opaque(Box<Self>),
|
||||||
|
TraitObject(Box<Self>),
|
||||||
|
TupleElement(Vec<(usize, Self)>),
|
||||||
|
Array(Box<Self>, u64),
|
||||||
|
/// The root of the unused_closures lint.
|
||||||
|
Closure(Span),
|
||||||
|
/// The root of the unused_generators lint.
|
||||||
|
Generator(Span),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(cx, expr), level = "debug", ret)]
|
||||||
|
fn is_ty_must_use<'tcx>(
|
||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
expr: &hir::Expr<'_>,
|
expr: &hir::Expr<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
descr_pre: &str,
|
) -> Option<MustUsePath> {
|
||||||
descr_post: &str,
|
|
||||||
plural_len: usize,
|
|
||||||
) -> bool {
|
|
||||||
if ty.is_unit()
|
if ty.is_unit()
|
||||||
|| !ty.is_inhabited_from(
|
|| !ty.is_inhabited_from(
|
||||||
cx.tcx,
|
cx.tcx,
|
||||||
@ -207,87 +241,164 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||||||
cx.param_env,
|
cx.param_env,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return true;
|
return Some(MustUsePath::Suppressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
let plural_suffix = pluralize!(plural_len);
|
|
||||||
|
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Adt(..) if ty.is_box() => {
|
ty::Adt(..) if ty.is_box() => {
|
||||||
let boxed_ty = ty.boxed_ty();
|
let boxed_ty = ty.boxed_ty();
|
||||||
let descr_pre = &format!("{}boxed ", descr_pre);
|
is_ty_must_use(cx, boxed_ty, expr, span)
|
||||||
check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len)
|
.map(|inner| MustUsePath::Boxed(Box::new(inner)))
|
||||||
}
|
}
|
||||||
ty::Adt(def, _) => check_must_use_def(cx, def.did(), span, descr_pre, descr_post),
|
ty::Adt(def, _) => is_def_must_use(cx, def.did(), span),
|
||||||
ty::Opaque(def, _) => {
|
ty::Opaque(def, _) => {
|
||||||
let mut has_emitted = false;
|
elaborate_predicates_with_span(
|
||||||
for obligation in elaborate_predicates_with_span(
|
|
||||||
cx.tcx,
|
cx.tcx,
|
||||||
cx.tcx.explicit_item_bounds(def).iter().cloned(),
|
cx.tcx.explicit_item_bounds(def).iter().cloned(),
|
||||||
) {
|
)
|
||||||
|
.filter_map(|obligation| {
|
||||||
// We only look at the `DefId`, so it is safe to skip the binder here.
|
// We only look at the `DefId`, so it is safe to skip the binder here.
|
||||||
if let ty::PredicateKind::Trait(ref poly_trait_predicate) =
|
if let ty::PredicateKind::Trait(ref poly_trait_predicate) =
|
||||||
obligation.predicate.kind().skip_binder()
|
obligation.predicate.kind().skip_binder()
|
||||||
{
|
{
|
||||||
let def_id = poly_trait_predicate.trait_ref.def_id;
|
let def_id = poly_trait_predicate.trait_ref.def_id;
|
||||||
let descr_pre =
|
|
||||||
&format!("{}implementer{} of ", descr_pre, plural_suffix,);
|
is_def_must_use(cx, def_id, span)
|
||||||
if check_must_use_def(cx, def_id, span, descr_pre, descr_post) {
|
} else {
|
||||||
has_emitted = true;
|
None
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
has_emitted
|
.map(|inner| MustUsePath::Opaque(Box::new(inner)))
|
||||||
|
.next()
|
||||||
}
|
}
|
||||||
ty::Dynamic(binder, _, _) => {
|
ty::Dynamic(binders, _, _) => binders
|
||||||
let mut has_emitted = false;
|
.iter()
|
||||||
for predicate in binder.iter() {
|
.filter_map(|predicate| {
|
||||||
if let ty::ExistentialPredicate::Trait(ref trait_ref) =
|
if let ty::ExistentialPredicate::Trait(ref trait_ref) =
|
||||||
predicate.skip_binder()
|
predicate.skip_binder()
|
||||||
{
|
{
|
||||||
let def_id = trait_ref.def_id;
|
let def_id = trait_ref.def_id;
|
||||||
let descr_post =
|
is_def_must_use(cx, def_id, span)
|
||||||
&format!(" trait object{}{}", plural_suffix, descr_post,);
|
} else {
|
||||||
if check_must_use_def(cx, def_id, span, descr_pre, descr_post) {
|
None
|
||||||
has_emitted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
.map(|inner| MustUsePath::TraitObject(Box::new(inner)))
|
||||||
has_emitted
|
})
|
||||||
}
|
.next(),
|
||||||
ty::Tuple(ref tys) => {
|
ty::Tuple(tys) => {
|
||||||
let mut has_emitted = false;
|
let elem_exprs = if let hir::ExprKind::Tup(elem_exprs) = expr.kind {
|
||||||
let comps = if let hir::ExprKind::Tup(comps) = expr.kind {
|
debug_assert_eq!(elem_exprs.len(), tys.len());
|
||||||
debug_assert_eq!(comps.len(), tys.len());
|
elem_exprs
|
||||||
comps
|
|
||||||
} else {
|
} else {
|
||||||
&[]
|
&[]
|
||||||
};
|
};
|
||||||
for (i, ty) in tys.iter().enumerate() {
|
|
||||||
let descr_post = &format!(" in tuple element {}", i);
|
// Default to `expr`.
|
||||||
let e = comps.get(i).unwrap_or(expr);
|
let elem_exprs = elem_exprs.iter().chain(iter::repeat(expr));
|
||||||
let span = e.span;
|
|
||||||
if check_must_use_ty(cx, ty, e, span, descr_pre, descr_post, plural_len) {
|
let nested_must_use = tys
|
||||||
has_emitted = true;
|
.iter()
|
||||||
}
|
.zip(elem_exprs)
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(i, (ty, expr))| {
|
||||||
|
is_ty_must_use(cx, ty, expr, expr.span).map(|path| (i, path))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if !nested_must_use.is_empty() {
|
||||||
|
Some(MustUsePath::TupleElement(nested_must_use))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
has_emitted
|
|
||||||
}
|
}
|
||||||
ty::Array(ty, len) => match len.try_eval_usize(cx.tcx, cx.param_env) {
|
ty::Array(ty, len) => match len.try_eval_usize(cx.tcx, cx.param_env) {
|
||||||
// If the array is empty we don't lint, to avoid false positives
|
// If the array is empty we don't lint, to avoid false positives
|
||||||
Some(0) | None => false,
|
Some(0) | None => None,
|
||||||
// If the array is definitely non-empty, we can do `#[must_use]` checking.
|
// If the array is definitely non-empty, we can do `#[must_use]` checking.
|
||||||
Some(n) => {
|
Some(len) => is_ty_must_use(cx, ty, expr, span)
|
||||||
let descr_pre = &format!("{}array{} of ", descr_pre, plural_suffix,);
|
.map(|inner| MustUsePath::Array(Box::new(inner), len)),
|
||||||
check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, n as usize + 1)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
ty::Closure(..) => {
|
ty::Closure(..) => Some(MustUsePath::Closure(span)),
|
||||||
|
ty::Generator(..) => Some(MustUsePath::Generator(span)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_def_must_use(cx: &LateContext<'_>, def_id: DefId, span: Span) -> Option<MustUsePath> {
|
||||||
|
if let Some(attr) = cx.tcx.get_attr(def_id, sym::must_use) {
|
||||||
|
// check for #[must_use = "..."]
|
||||||
|
let reason = attr.value_str();
|
||||||
|
Some(MustUsePath::Def(span, def_id, reason))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns whether further errors should be suppressed because either a lint has been emitted or the type should be ignored.
|
||||||
|
fn check_must_use_def(
|
||||||
|
cx: &LateContext<'_>,
|
||||||
|
def_id: DefId,
|
||||||
|
span: Span,
|
||||||
|
descr_pre_path: &str,
|
||||||
|
descr_post_path: &str,
|
||||||
|
) -> bool {
|
||||||
|
is_def_must_use(cx, def_id, span)
|
||||||
|
.map(|must_use_path| {
|
||||||
|
emit_must_use_untranslated(
|
||||||
|
cx,
|
||||||
|
&must_use_path,
|
||||||
|
descr_pre_path,
|
||||||
|
descr_post_path,
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(cx), level = "debug")]
|
||||||
|
fn emit_must_use_untranslated(
|
||||||
|
cx: &LateContext<'_>,
|
||||||
|
path: &MustUsePath,
|
||||||
|
descr_pre: &str,
|
||||||
|
descr_post: &str,
|
||||||
|
plural_len: usize,
|
||||||
|
) {
|
||||||
|
let plural_suffix = pluralize!(plural_len);
|
||||||
|
|
||||||
|
match path {
|
||||||
|
MustUsePath::Suppressed => {}
|
||||||
|
MustUsePath::Boxed(path) => {
|
||||||
|
let descr_pre = &format!("{}boxed ", descr_pre);
|
||||||
|
emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len);
|
||||||
|
}
|
||||||
|
MustUsePath::Opaque(path) => {
|
||||||
|
let descr_pre = &format!("{}implementer{} of ", descr_pre, plural_suffix);
|
||||||
|
emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len);
|
||||||
|
}
|
||||||
|
MustUsePath::TraitObject(path) => {
|
||||||
|
let descr_post = &format!(" trait object{}{}", plural_suffix, descr_post);
|
||||||
|
emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len);
|
||||||
|
}
|
||||||
|
MustUsePath::TupleElement(elems) => {
|
||||||
|
for (index, path) in elems {
|
||||||
|
let descr_post = &format!(" in tuple element {}", index);
|
||||||
|
emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MustUsePath::Array(path, len) => {
|
||||||
|
let descr_pre = &format!("{}array{} of ", descr_pre, plural_suffix);
|
||||||
|
emit_must_use_untranslated(
|
||||||
|
cx,
|
||||||
|
path,
|
||||||
|
descr_pre,
|
||||||
|
descr_post,
|
||||||
|
plural_len.saturating_add(usize::try_from(*len).unwrap_or(usize::MAX)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
MustUsePath::Closure(span) => {
|
||||||
cx.struct_span_lint(
|
cx.struct_span_lint(
|
||||||
UNUSED_MUST_USE,
|
UNUSED_MUST_USE,
|
||||||
span,
|
*span,
|
||||||
fluent::lint_unused_closure,
|
fluent::lint_unused_closure,
|
||||||
|lint| {
|
|lint| {
|
||||||
// FIXME(davidtwco): this isn't properly translatable because of the
|
// FIXME(davidtwco): this isn't properly translatable because of the
|
||||||
@ -298,12 +409,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||||||
.note(fluent::note)
|
.note(fluent::note)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
true
|
|
||||||
}
|
}
|
||||||
ty::Generator(..) => {
|
MustUsePath::Generator(span) => {
|
||||||
cx.struct_span_lint(
|
cx.struct_span_lint(
|
||||||
UNUSED_MUST_USE,
|
UNUSED_MUST_USE,
|
||||||
span,
|
*span,
|
||||||
fluent::lint_unused_generator,
|
fluent::lint_unused_generator,
|
||||||
|lint| {
|
|lint| {
|
||||||
// FIXME(davidtwco): this isn't properly translatable because of the
|
// FIXME(davidtwco): this isn't properly translatable because of the
|
||||||
@ -314,40 +424,20 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||||||
.note(fluent::note)
|
.note(fluent::note)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
true
|
|
||||||
}
|
}
|
||||||
_ => false,
|
MustUsePath::Def(span, def_id, reason) => {
|
||||||
}
|
cx.struct_span_lint(UNUSED_MUST_USE, *span, fluent::lint_unused_def, |lint| {
|
||||||
}
|
// FIXME(davidtwco): this isn't properly translatable because of the pre/post
|
||||||
|
// strings
|
||||||
// Returns whether an error has been emitted (and thus another does not need to be later).
|
lint.set_arg("pre", descr_pre);
|
||||||
// FIXME: Args desc_{pre,post}_path could be made lazy by taking Fn() -> &str, but this
|
lint.set_arg("post", descr_post);
|
||||||
// would make calling it a big awkward. Could also take String (so args are moved), but
|
lint.set_arg("def", cx.tcx.def_path_str(*def_id));
|
||||||
// this would still require a copy into the format string, which would only be executed
|
if let Some(note) = reason {
|
||||||
// when needed.
|
lint.note(note.as_str());
|
||||||
fn check_must_use_def(
|
}
|
||||||
cx: &LateContext<'_>,
|
lint
|
||||||
def_id: DefId,
|
});
|
||||||
span: Span,
|
}
|
||||||
descr_pre_path: &str,
|
|
||||||
descr_post_path: &str,
|
|
||||||
) -> bool {
|
|
||||||
if let Some(attr) = cx.tcx.get_attr(def_id, sym::must_use) {
|
|
||||||
cx.struct_span_lint(UNUSED_MUST_USE, span, fluent::lint_unused_def, |lint| {
|
|
||||||
// FIXME(davidtwco): this isn't properly translatable because of the pre/post
|
|
||||||
// strings
|
|
||||||
lint.set_arg("pre", descr_pre_path);
|
|
||||||
lint.set_arg("post", descr_post_path);
|
|
||||||
lint.set_arg("def", cx.tcx.def_path_str(def_id));
|
|
||||||
// check for #[must_use = "..."]
|
|
||||||
if let Some(note) = attr.value_str() {
|
|
||||||
lint.note(note.as_str());
|
|
||||||
}
|
|
||||||
lint
|
|
||||||
});
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -692,6 +692,7 @@ pub struct CrateLocationUnknownType<'a> {
|
|||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub path: &'a Path,
|
pub path: &'a Path,
|
||||||
|
pub crate_name: Symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -707,6 +707,12 @@ impl<'a> CrateLocator<'a> {
|
|||||||
loc.original().clone(),
|
loc.original().clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
if !loc.original().is_file() {
|
||||||
|
return Err(CrateError::ExternLocationNotFile(
|
||||||
|
self.crate_name,
|
||||||
|
loc.original().clone(),
|
||||||
|
));
|
||||||
|
}
|
||||||
let Some(file) = loc.original().file_name().and_then(|s| s.to_str()) else {
|
let Some(file) = loc.original().file_name().and_then(|s| s.to_str()) else {
|
||||||
return Err(CrateError::ExternLocationNotFile(
|
return Err(CrateError::ExternLocationNotFile(
|
||||||
self.crate_name,
|
self.crate_name,
|
||||||
@ -1020,11 +1026,10 @@ impl CrateError {
|
|||||||
None => String::new(),
|
None => String::new(),
|
||||||
Some(r) => format!(" which `{}` depends on", r.name),
|
Some(r) => format!(" which `{}` depends on", r.name),
|
||||||
};
|
};
|
||||||
// FIXME: There are no tests for CrateLocationUnknownType or LibFilenameForm
|
|
||||||
if !locator.crate_rejections.via_filename.is_empty() {
|
if !locator.crate_rejections.via_filename.is_empty() {
|
||||||
let mismatches = locator.crate_rejections.via_filename.iter();
|
let mismatches = locator.crate_rejections.via_filename.iter();
|
||||||
for CrateMismatch { path, .. } in mismatches {
|
for CrateMismatch { path, .. } in mismatches {
|
||||||
sess.emit_err(CrateLocationUnknownType { span, path: &path });
|
sess.emit_err(CrateLocationUnknownType { span, path: &path, crate_name });
|
||||||
sess.emit_err(LibFilenameForm {
|
sess.emit_err(LibFilenameForm {
|
||||||
span,
|
span,
|
||||||
dll_prefix: &locator.dll_prefix,
|
dll_prefix: &locator.dll_prefix,
|
||||||
|
@ -36,6 +36,11 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
|
|||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.param_env
|
self.param_env
|
||||||
}
|
}
|
||||||
@ -43,6 +48,10 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
|
|||||||
true
|
true
|
||||||
} // irrelevant
|
} // irrelevant
|
||||||
|
|
||||||
|
fn mark_ambiguous(&mut self) {
|
||||||
|
bug!()
|
||||||
|
}
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: ty::Variance,
|
_: ty::Variance,
|
||||||
|
@ -42,7 +42,6 @@ where
|
|||||||
ClosureSimplifiedType(D),
|
ClosureSimplifiedType(D),
|
||||||
GeneratorSimplifiedType(D),
|
GeneratorSimplifiedType(D),
|
||||||
GeneratorWitnessSimplifiedType(usize),
|
GeneratorWitnessSimplifiedType(usize),
|
||||||
OpaqueSimplifiedType(D),
|
|
||||||
FunctionSimplifiedType(usize),
|
FunctionSimplifiedType(usize),
|
||||||
PlaceholderSimplifiedType,
|
PlaceholderSimplifiedType,
|
||||||
}
|
}
|
||||||
@ -127,7 +126,7 @@ pub fn simplify_type<'tcx>(
|
|||||||
TreatParams::AsPlaceholder => Some(PlaceholderSimplifiedType),
|
TreatParams::AsPlaceholder => Some(PlaceholderSimplifiedType),
|
||||||
TreatParams::AsInfer => None,
|
TreatParams::AsInfer => None,
|
||||||
},
|
},
|
||||||
ty::Projection(_) => match treat_params {
|
ty::Opaque(..) | ty::Projection(_) => match treat_params {
|
||||||
// When treating `ty::Param` as a placeholder, projections also
|
// When treating `ty::Param` as a placeholder, projections also
|
||||||
// don't unify with anything else as long as they are fully normalized.
|
// don't unify with anything else as long as they are fully normalized.
|
||||||
//
|
//
|
||||||
@ -138,7 +137,6 @@ pub fn simplify_type<'tcx>(
|
|||||||
}
|
}
|
||||||
TreatParams::AsPlaceholder | TreatParams::AsInfer => None,
|
TreatParams::AsPlaceholder | TreatParams::AsInfer => None,
|
||||||
},
|
},
|
||||||
ty::Opaque(def_id, _) => Some(OpaqueSimplifiedType(def_id)),
|
|
||||||
ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)),
|
ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)),
|
||||||
ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None,
|
ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None,
|
||||||
}
|
}
|
||||||
@ -151,8 +149,7 @@ impl<D: Copy + Debug + Eq> SimplifiedTypeGen<D> {
|
|||||||
| ForeignSimplifiedType(d)
|
| ForeignSimplifiedType(d)
|
||||||
| TraitSimplifiedType(d)
|
| TraitSimplifiedType(d)
|
||||||
| ClosureSimplifiedType(d)
|
| ClosureSimplifiedType(d)
|
||||||
| GeneratorSimplifiedType(d)
|
| GeneratorSimplifiedType(d) => Some(d),
|
||||||
| OpaqueSimplifiedType(d) => Some(d),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,7 +179,6 @@ impl<D: Copy + Debug + Eq> SimplifiedTypeGen<D> {
|
|||||||
ClosureSimplifiedType(d) => ClosureSimplifiedType(map(d)),
|
ClosureSimplifiedType(d) => ClosureSimplifiedType(map(d)),
|
||||||
GeneratorSimplifiedType(d) => GeneratorSimplifiedType(map(d)),
|
GeneratorSimplifiedType(d) => GeneratorSimplifiedType(map(d)),
|
||||||
GeneratorWitnessSimplifiedType(n) => GeneratorWitnessSimplifiedType(n),
|
GeneratorWitnessSimplifiedType(n) => GeneratorWitnessSimplifiedType(n),
|
||||||
OpaqueSimplifiedType(d) => OpaqueSimplifiedType(map(d)),
|
|
||||||
FunctionSimplifiedType(n) => FunctionSimplifiedType(n),
|
FunctionSimplifiedType(n) => FunctionSimplifiedType(n),
|
||||||
PlaceholderSimplifiedType => PlaceholderSimplifiedType,
|
PlaceholderSimplifiedType => PlaceholderSimplifiedType,
|
||||||
}
|
}
|
||||||
@ -229,7 +225,7 @@ impl DeepRejectCtxt {
|
|||||||
match impl_ty.kind() {
|
match impl_ty.kind() {
|
||||||
// Start by checking whether the type in the impl may unify with
|
// Start by checking whether the type in the impl may unify with
|
||||||
// pretty much everything. Just return `true` in that case.
|
// pretty much everything. Just return `true` in that case.
|
||||||
ty::Param(_) | ty::Projection(_) | ty::Error(_) => return true,
|
ty::Param(_) | ty::Projection(_) | ty::Error(_) | ty::Opaque(..) => return true,
|
||||||
// These types only unify with inference variables or their own
|
// These types only unify with inference variables or their own
|
||||||
// variant.
|
// variant.
|
||||||
ty::Bool
|
ty::Bool
|
||||||
@ -247,8 +243,7 @@ impl DeepRejectCtxt {
|
|||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Tuple(..)
|
| ty::Tuple(..)
|
||||||
| ty::FnPtr(..)
|
| ty::FnPtr(..)
|
||||||
| ty::Foreign(..)
|
| ty::Foreign(..) => {}
|
||||||
| ty::Opaque(..) => {}
|
|
||||||
ty::FnDef(..)
|
ty::FnDef(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::Generator(..)
|
| ty::Generator(..)
|
||||||
@ -328,10 +323,7 @@ impl DeepRejectCtxt {
|
|||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Opaque types in impls should be forbidden, but that doesn't
|
ty::Opaque(..) => true,
|
||||||
// stop compilation. So this match arm should never return true
|
|
||||||
// if compilation succeeds.
|
|
||||||
ty::Opaque(..) => matches!(k, ty::Opaque(..)),
|
|
||||||
|
|
||||||
// Impls cannot contain these types as these cannot be named directly.
|
// Impls cannot contain these types as these cannot be named directly.
|
||||||
ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) => false,
|
ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) => false,
|
||||||
|
@ -259,6 +259,7 @@ impl FlagComputation {
|
|||||||
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
|
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
|
||||||
self.add_ty(ty);
|
self.add_ty(ty);
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Ambiguous => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,6 +620,7 @@ impl<'tcx> Predicate<'tcx> {
|
|||||||
| PredicateKind::Coerce(_)
|
| PredicateKind::Coerce(_)
|
||||||
| PredicateKind::ConstEvaluatable(_)
|
| PredicateKind::ConstEvaluatable(_)
|
||||||
| PredicateKind::ConstEquate(_, _)
|
| PredicateKind::ConstEquate(_, _)
|
||||||
|
| PredicateKind::Ambiguous
|
||||||
| PredicateKind::TypeWellFormedFromEnv(_) => true,
|
| PredicateKind::TypeWellFormedFromEnv(_) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -702,6 +703,10 @@ pub enum PredicateKind<'tcx> {
|
|||||||
///
|
///
|
||||||
/// Only used for Chalk.
|
/// Only used for Chalk.
|
||||||
TypeWellFormedFromEnv(Ty<'tcx>),
|
TypeWellFormedFromEnv(Ty<'tcx>),
|
||||||
|
|
||||||
|
/// A marker predicate that is always ambiguous.
|
||||||
|
/// Used for coherence to mark opaque types as possibly equal to each other but ambiguous.
|
||||||
|
Ambiguous,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The crate outlives map is computed during typeck and contains the
|
/// The crate outlives map is computed during typeck and contains the
|
||||||
@ -1186,6 +1191,7 @@ impl<'tcx> Predicate<'tcx> {
|
|||||||
| PredicateKind::TypeOutlives(..)
|
| PredicateKind::TypeOutlives(..)
|
||||||
| PredicateKind::ConstEvaluatable(..)
|
| PredicateKind::ConstEvaluatable(..)
|
||||||
| PredicateKind::ConstEquate(..)
|
| PredicateKind::ConstEquate(..)
|
||||||
|
| PredicateKind::Ambiguous
|
||||||
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1204,6 +1210,7 @@ impl<'tcx> Predicate<'tcx> {
|
|||||||
| PredicateKind::TypeOutlives(..)
|
| PredicateKind::TypeOutlives(..)
|
||||||
| PredicateKind::ConstEvaluatable(..)
|
| PredicateKind::ConstEvaluatable(..)
|
||||||
| PredicateKind::ConstEquate(..)
|
| PredicateKind::ConstEquate(..)
|
||||||
|
| PredicateKind::Ambiguous
|
||||||
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1222,6 +1229,7 @@ impl<'tcx> Predicate<'tcx> {
|
|||||||
| PredicateKind::ClosureKind(..)
|
| PredicateKind::ClosureKind(..)
|
||||||
| PredicateKind::ConstEvaluatable(..)
|
| PredicateKind::ConstEvaluatable(..)
|
||||||
| PredicateKind::ConstEquate(..)
|
| PredicateKind::ConstEquate(..)
|
||||||
|
| PredicateKind::Ambiguous
|
||||||
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2704,6 +2704,7 @@ define_print_and_forward_display! {
|
|||||||
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
|
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
|
||||||
p!("the type `", print(ty), "` is found in the environment")
|
p!("the type `", print(ty), "` is found in the environment")
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Ambiguous => p!("ambiguous"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@ pub enum Cause {
|
|||||||
pub trait TypeRelation<'tcx>: Sized {
|
pub trait TypeRelation<'tcx>: Sized {
|
||||||
fn tcx(&self) -> TyCtxt<'tcx>;
|
fn tcx(&self) -> TyCtxt<'tcx>;
|
||||||
|
|
||||||
|
fn intercrate(&self) -> bool;
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx>;
|
fn param_env(&self) -> ty::ParamEnv<'tcx>;
|
||||||
|
|
||||||
/// Returns a static string we can use for printouts.
|
/// Returns a static string we can use for printouts.
|
||||||
@ -32,6 +34,9 @@ pub trait TypeRelation<'tcx>: Sized {
|
|||||||
/// relation. Just affects error messages.
|
/// relation. Just affects error messages.
|
||||||
fn a_is_expected(&self) -> bool;
|
fn a_is_expected(&self) -> bool;
|
||||||
|
|
||||||
|
/// Used during coherence. If called, must emit an always-ambiguous obligation.
|
||||||
|
fn mark_ambiguous(&mut self);
|
||||||
|
|
||||||
fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> R
|
fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> R,
|
F: FnOnce(&mut Self) -> R,
|
||||||
@ -562,16 +567,23 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
|
|||||||
(&ty::Opaque(a_def_id, a_substs), &ty::Opaque(b_def_id, b_substs))
|
(&ty::Opaque(a_def_id, a_substs), &ty::Opaque(b_def_id, b_substs))
|
||||||
if a_def_id == b_def_id =>
|
if a_def_id == b_def_id =>
|
||||||
{
|
{
|
||||||
let opt_variances = tcx.variances_of(a_def_id);
|
if relation.intercrate() {
|
||||||
let substs = relate_substs_with_variances(
|
// During coherence, opaque types should be treated as equal to each other, even if their generic params
|
||||||
relation,
|
// differ, as they could resolve to the same hidden type, even for different generic params.
|
||||||
a_def_id,
|
relation.mark_ambiguous();
|
||||||
opt_variances,
|
Ok(a)
|
||||||
a_substs,
|
} else {
|
||||||
b_substs,
|
let opt_variances = tcx.variances_of(a_def_id);
|
||||||
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
|
let substs = relate_substs_with_variances(
|
||||||
)?;
|
relation,
|
||||||
Ok(tcx.mk_opaque(a_def_id, substs))
|
a_def_id,
|
||||||
|
opt_variances,
|
||||||
|
a_substs,
|
||||||
|
b_substs,
|
||||||
|
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
|
||||||
|
)?;
|
||||||
|
Ok(tcx.mk_opaque(a_def_id, substs))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => Err(TypeError::Sorts(expected_found(relation, a, b))),
|
_ => Err(TypeError::Sorts(expected_found(relation, a, b))),
|
||||||
|
@ -173,6 +173,7 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
|
|||||||
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
|
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
|
||||||
write!(f, "TypeWellFormedFromEnv({:?})", ty)
|
write!(f, "TypeWellFormedFromEnv({:?})", ty)
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -841,6 +841,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
|
||||||
|
ty::PredicateKind::Ambiguous => return false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
@ -18,7 +18,7 @@ use rustc_data_structures::fx::FxIndexSet;
|
|||||||
use rustc_errors::Diagnostic;
|
use rustc_errors::Diagnostic;
|
||||||
use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||||
use rustc_hir::CRATE_HIR_ID;
|
use rustc_hir::CRATE_HIR_ID;
|
||||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::util;
|
use rustc_infer::traits::util;
|
||||||
use rustc_middle::traits::specialization_graph::OverlapMode;
|
use rustc_middle::traits::specialization_graph::OverlapMode;
|
||||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||||
@ -94,8 +94,9 @@ pub fn overlapping_impls<'tcx>(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx =
|
||||||
let selcx = &mut SelectionContext::intercrate(&infcx);
|
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).intercrate().build();
|
||||||
|
let selcx = &mut SelectionContext::new(&infcx);
|
||||||
let overlaps =
|
let overlaps =
|
||||||
overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some();
|
overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some();
|
||||||
if !overlaps {
|
if !overlaps {
|
||||||
@ -105,8 +106,9 @@ pub fn overlapping_impls<'tcx>(
|
|||||||
// In the case where we detect an error, run the check again, but
|
// In the case where we detect an error, run the check again, but
|
||||||
// this time tracking intercrate ambiguity causes for better
|
// this time tracking intercrate ambiguity causes for better
|
||||||
// diagnostics. (These take time and can lead to false errors.)
|
// diagnostics. (These take time and can lead to false errors.)
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx =
|
||||||
let selcx = &mut SelectionContext::intercrate(&infcx);
|
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).intercrate().build();
|
||||||
|
let selcx = &mut SelectionContext::new(&infcx);
|
||||||
selcx.enable_tracking_intercrate_ambiguity_causes();
|
selcx.enable_tracking_intercrate_ambiguity_causes();
|
||||||
Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap())
|
Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap())
|
||||||
}
|
}
|
||||||
|
@ -1168,6 +1168,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty::PredicateKind::Ambiguous => span_bug!(span, "ambiguous"),
|
||||||
|
|
||||||
ty::PredicateKind::TypeWellFormedFromEnv(..) => span_bug!(
|
ty::PredicateKind::TypeWellFormedFromEnv(..) => span_bug!(
|
||||||
span,
|
span,
|
||||||
"TypeWellFormedFromEnv predicate should only exist in the environment"
|
"TypeWellFormedFromEnv predicate should only exist in the environment"
|
||||||
|
@ -336,6 +336,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||||||
ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder));
|
ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder));
|
||||||
ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)]))
|
ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)]))
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
|
||||||
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
bug!("TypeWellFormedFromEnv is only used for Chalk")
|
bug!("TypeWellFormedFromEnv is only used for Chalk")
|
||||||
}
|
}
|
||||||
@ -569,6 +570,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
|
||||||
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
bug!("TypeWellFormedFromEnv is only used for Chalk")
|
bug!("TypeWellFormedFromEnv is only used for Chalk")
|
||||||
}
|
}
|
||||||
|
@ -319,6 +319,7 @@ fn predicate_references_self<'tcx>(
|
|||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,6 +351,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|||||||
| ty::PredicateKind::TypeOutlives(..)
|
| ty::PredicateKind::TypeOutlives(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => false,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -110,25 +110,6 @@ pub struct SelectionContext<'cx, 'tcx> {
|
|||||||
/// require themselves.
|
/// require themselves.
|
||||||
freshener: TypeFreshener<'cx, 'tcx>,
|
freshener: TypeFreshener<'cx, 'tcx>,
|
||||||
|
|
||||||
/// During coherence we have to assume that other crates may add
|
|
||||||
/// additional impls which we currently don't know about.
|
|
||||||
///
|
|
||||||
/// To deal with this evaluation should be conservative
|
|
||||||
/// and consider the possibility of impls from outside this crate.
|
|
||||||
/// This comes up primarily when resolving ambiguity. Imagine
|
|
||||||
/// there is some trait reference `$0: Bar` where `$0` is an
|
|
||||||
/// inference variable. If `intercrate` is true, then we can never
|
|
||||||
/// say for sure that this reference is not implemented, even if
|
|
||||||
/// there are *no impls at all for `Bar`*, because `$0` could be
|
|
||||||
/// bound to some type that in a downstream crate that implements
|
|
||||||
/// `Bar`.
|
|
||||||
///
|
|
||||||
/// Outside of coherence we set this to false because we are only
|
|
||||||
/// interested in types that the user could actually have written.
|
|
||||||
/// In other words, we consider `$0: Bar` to be unimplemented if
|
|
||||||
/// there is no type that the user could *actually name* that
|
|
||||||
/// would satisfy it. This avoids crippling inference, basically.
|
|
||||||
intercrate: bool,
|
|
||||||
/// If `intercrate` is set, we remember predicates which were
|
/// If `intercrate` is set, we remember predicates which were
|
||||||
/// considered ambiguous because of impls potentially added in other crates.
|
/// considered ambiguous because of impls potentially added in other crates.
|
||||||
/// This is used in coherence to give improved diagnostics.
|
/// This is used in coherence to give improved diagnostics.
|
||||||
@ -226,16 +207,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
SelectionContext {
|
SelectionContext {
|
||||||
infcx,
|
infcx,
|
||||||
freshener: infcx.freshener_keep_static(),
|
freshener: infcx.freshener_keep_static(),
|
||||||
intercrate: false,
|
|
||||||
intercrate_ambiguity_causes: None,
|
intercrate_ambiguity_causes: None,
|
||||||
query_mode: TraitQueryMode::Standard,
|
query_mode: TraitQueryMode::Standard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intercrate(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> {
|
|
||||||
SelectionContext { intercrate: true, ..SelectionContext::new(infcx) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_query_mode(
|
pub fn with_query_mode(
|
||||||
infcx: &'cx InferCtxt<'tcx>,
|
infcx: &'cx InferCtxt<'tcx>,
|
||||||
query_mode: TraitQueryMode,
|
query_mode: TraitQueryMode,
|
||||||
@ -247,7 +223,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
/// Enables tracking of intercrate ambiguity causes. See
|
/// Enables tracking of intercrate ambiguity causes. See
|
||||||
/// the documentation of [`Self::intercrate_ambiguity_causes`] for more.
|
/// the documentation of [`Self::intercrate_ambiguity_causes`] for more.
|
||||||
pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
|
pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
|
||||||
assert!(self.intercrate);
|
assert!(self.is_intercrate());
|
||||||
assert!(self.intercrate_ambiguity_causes.is_none());
|
assert!(self.intercrate_ambiguity_causes.is_none());
|
||||||
self.intercrate_ambiguity_causes = Some(FxIndexSet::default());
|
self.intercrate_ambiguity_causes = Some(FxIndexSet::default());
|
||||||
debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
|
debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
|
||||||
@ -257,7 +233,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
/// was enabled and disables tracking at the same time. If
|
/// was enabled and disables tracking at the same time. If
|
||||||
/// tracking is not enabled, just returns an empty vector.
|
/// tracking is not enabled, just returns an empty vector.
|
||||||
pub fn take_intercrate_ambiguity_causes(&mut self) -> FxIndexSet<IntercrateAmbiguityCause> {
|
pub fn take_intercrate_ambiguity_causes(&mut self) -> FxIndexSet<IntercrateAmbiguityCause> {
|
||||||
assert!(self.intercrate);
|
assert!(self.is_intercrate());
|
||||||
self.intercrate_ambiguity_causes.take().unwrap_or_default()
|
self.intercrate_ambiguity_causes.take().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +246,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_intercrate(&self) -> bool {
|
pub fn is_intercrate(&self) -> bool {
|
||||||
self.intercrate
|
self.infcx.intercrate
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -741,6 +717,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
bug!("TypeWellFormedFromEnv is only used for chalk")
|
bug!("TypeWellFormedFromEnv is only used for chalk")
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -751,7 +728,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
previous_stack: TraitObligationStackList<'o, 'tcx>,
|
previous_stack: TraitObligationStackList<'o, 'tcx>,
|
||||||
mut obligation: TraitObligation<'tcx>,
|
mut obligation: TraitObligation<'tcx>,
|
||||||
) -> Result<EvaluationResult, OverflowError> {
|
) -> Result<EvaluationResult, OverflowError> {
|
||||||
if !self.intercrate
|
if !self.is_intercrate()
|
||||||
&& obligation.is_global()
|
&& obligation.is_global()
|
||||||
&& obligation.param_env.caller_bounds().iter().all(|bound| bound.needs_subst())
|
&& obligation.param_env.caller_bounds().iter().all(|bound| bound.needs_subst())
|
||||||
{
|
{
|
||||||
@ -1014,7 +991,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// mode, so don't do any caching. In particular, we might
|
// mode, so don't do any caching. In particular, we might
|
||||||
// re-use the same `InferCtxt` with both an intercrate
|
// re-use the same `InferCtxt` with both an intercrate
|
||||||
// and non-intercrate `SelectionContext`
|
// and non-intercrate `SelectionContext`
|
||||||
if self.intercrate {
|
if self.is_intercrate() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1044,7 +1021,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// mode, so don't do any caching. In particular, we might
|
// mode, so don't do any caching. In particular, we might
|
||||||
// re-use the same `InferCtxt` with both an intercrate
|
// re-use the same `InferCtxt` with both an intercrate
|
||||||
// and non-intercrate `SelectionContext`
|
// and non-intercrate `SelectionContext`
|
||||||
if self.intercrate {
|
if self.is_intercrate() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1225,9 +1202,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
|
fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
|
||||||
debug!("is_knowable(intercrate={:?})", self.intercrate);
|
debug!("is_knowable(intercrate={:?})", self.is_intercrate());
|
||||||
|
|
||||||
if !self.intercrate || stack.obligation.polarity() == ty::ImplPolarity::Negative {
|
if !self.is_intercrate() || stack.obligation.polarity() == ty::ImplPolarity::Negative {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1258,7 +1235,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// the master cache. Since coherence executes pretty quickly,
|
// the master cache. Since coherence executes pretty quickly,
|
||||||
// it's not worth going to more trouble to increase the
|
// it's not worth going to more trouble to increase the
|
||||||
// hit-rate, I don't think.
|
// hit-rate, I don't think.
|
||||||
if self.intercrate {
|
if self.is_intercrate() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1275,7 +1252,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// mode, so don't do any caching. In particular, we might
|
// mode, so don't do any caching. In particular, we might
|
||||||
// re-use the same `InferCtxt` with both an intercrate
|
// re-use the same `InferCtxt` with both an intercrate
|
||||||
// and non-intercrate `SelectionContext`
|
// and non-intercrate `SelectionContext`
|
||||||
if self.intercrate {
|
if self.is_intercrate() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
@ -1314,7 +1291,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// mode, so don't do any caching. In particular, we might
|
// mode, so don't do any caching. In particular, we might
|
||||||
// re-use the same `InferCtxt` with both an intercrate
|
// re-use the same `InferCtxt` with both an intercrate
|
||||||
// and non-intercrate `SelectionContext`
|
// and non-intercrate `SelectionContext`
|
||||||
if self.intercrate {
|
if self.is_intercrate() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
match result {
|
match result {
|
||||||
@ -2191,7 +2168,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
.map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{e}`"))?;
|
.map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{e}`"))?;
|
||||||
nested_obligations.extend(obligations);
|
nested_obligations.extend(obligations);
|
||||||
|
|
||||||
if !self.intercrate
|
if !self.is_intercrate()
|
||||||
&& self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation
|
&& self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation
|
||||||
{
|
{
|
||||||
debug!("reservation impls only apply in intercrate mode");
|
debug!("reservation impls only apply in intercrate mode");
|
||||||
|
@ -155,6 +155,7 @@ pub fn predicate_obligations<'tcx>(
|
|||||||
wf.compute(c1.into());
|
wf.compute(c1.into());
|
||||||
wf.compute(c2.into());
|
wf.compute(c2.into());
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Ambiguous => {}
|
||||||
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
bug!("TypeWellFormedFromEnv is only used for Chalk")
|
bug!("TypeWellFormedFromEnv is only used for Chalk")
|
||||||
}
|
}
|
||||||
@ -875,6 +876,7 @@ pub(crate) fn required_region_bounds<'tcx>(
|
|||||||
| ty::PredicateKind::RegionOutlives(..)
|
| ty::PredicateKind::RegionOutlives(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
|
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
|
||||||
// Search for a bound of the form `erased_self_ty
|
// Search for a bound of the form `erased_self_ty
|
||||||
|
@ -121,6 +121,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
|||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
|
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
|
||||||
};
|
};
|
||||||
let value = chalk_ir::ProgramClauseImplication {
|
let value = chalk_ir::ProgramClauseImplication {
|
||||||
@ -212,6 +213,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
|
|||||||
ty::PredicateKind::ClosureKind(..)
|
ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::ConstEquate(..) => {
|
| ty::PredicateKind::ConstEquate(..) => {
|
||||||
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
|
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
|
||||||
}
|
}
|
||||||
@ -625,6 +627,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
|
|||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
bug!("unexpected predicate {}", &self)
|
bug!("unexpected predicate {}", &self)
|
||||||
}
|
}
|
||||||
@ -754,6 +757,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
|
|||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
bug!("unexpected predicate {}", &self)
|
bug!("unexpected predicate {}", &self)
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,7 @@ fn compute_implied_outlives_bounds<'tcx>(
|
|||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
ty::PredicateKind::WellFormed(arg) => {
|
ty::PredicateKind::WellFormed(arg) => {
|
||||||
wf_args.push(arg);
|
wf_args.push(arg);
|
||||||
|
@ -66,6 +66,7 @@ fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool {
|
|||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => true,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
#![feature(iter_next_chunk)]
|
#![feature(iter_next_chunk)]
|
||||||
#![feature(repr_simd)]
|
#![feature(repr_simd)]
|
||||||
#![feature(slice_partition_dedup)]
|
#![feature(slice_partition_dedup)]
|
||||||
|
#![feature(strict_provenance)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
#![deny(fuzzy_provenance_casts)]
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
//
|
//
|
||||||
// Lints:
|
// Lints:
|
||||||
#![deny(unsafe_op_in_unsafe_fn)]
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
#![deny(fuzzy_provenance_casts)]
|
||||||
#![warn(deprecated_in_future)]
|
#![warn(deprecated_in_future)]
|
||||||
#![warn(missing_debug_implementations)]
|
#![warn(missing_debug_implementations)]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_format() {
|
fn test_format() {
|
||||||
@ -76,14 +77,14 @@ fn test_format_macro_interface() {
|
|||||||
t!(format!("{}", "foo"), "foo");
|
t!(format!("{}", "foo"), "foo");
|
||||||
t!(format!("{}", "foo".to_string()), "foo");
|
t!(format!("{}", "foo".to_string()), "foo");
|
||||||
if cfg!(target_pointer_width = "32") {
|
if cfg!(target_pointer_width = "32") {
|
||||||
t!(format!("{:#p}", 0x1234 as *const isize), "0x00001234");
|
t!(format!("{:#p}", ptr::invalid::<isize>(0x1234)), "0x00001234");
|
||||||
t!(format!("{:#p}", 0x1234 as *mut isize), "0x00001234");
|
t!(format!("{:#p}", ptr::invalid_mut::<isize>(0x1234)), "0x00001234");
|
||||||
} else {
|
} else {
|
||||||
t!(format!("{:#p}", 0x1234 as *const isize), "0x0000000000001234");
|
t!(format!("{:#p}", ptr::invalid::<isize>(0x1234)), "0x0000000000001234");
|
||||||
t!(format!("{:#p}", 0x1234 as *mut isize), "0x0000000000001234");
|
t!(format!("{:#p}", ptr::invalid_mut::<isize>(0x1234)), "0x0000000000001234");
|
||||||
}
|
}
|
||||||
t!(format!("{:p}", 0x1234 as *const isize), "0x1234");
|
t!(format!("{:p}", ptr::invalid::<isize>(0x1234)), "0x1234");
|
||||||
t!(format!("{:p}", 0x1234 as *mut isize), "0x1234");
|
t!(format!("{:p}", ptr::invalid_mut::<isize>(0x1234)), "0x1234");
|
||||||
t!(format!("{A:x}"), "aloha");
|
t!(format!("{A:x}"), "aloha");
|
||||||
t!(format!("{B:X}"), "adios");
|
t!(format!("{B:X}"), "adios");
|
||||||
t!(format!("foo {} ☃☃☃☃☃☃", "bar"), "foo bar ☃☃☃☃☃☃");
|
t!(format!("foo {} ☃☃☃☃☃☃", "bar"), "foo bar ☃☃☃☃☃☃");
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#![feature(strict_provenance)]
|
#![feature(strict_provenance)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(drain_keep_rest)]
|
#![feature(drain_keep_rest)]
|
||||||
|
#![deny(fuzzy_provenance_casts)]
|
||||||
|
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
@ -220,6 +220,7 @@
|
|||||||
#![allow(explicit_outlives_requirements)]
|
#![allow(explicit_outlives_requirements)]
|
||||||
#![allow(unused_lifetimes)]
|
#![allow(unused_lifetimes)]
|
||||||
#![deny(rustc::existing_doc_keyword)]
|
#![deny(rustc::existing_doc_keyword)]
|
||||||
|
#![deny(fuzzy_provenance_casts)]
|
||||||
// Ensure that std can be linked against panic_abort despite compiled with `-C panic=unwind`
|
// Ensure that std can be linked against panic_abort despite compiled with `-C panic=unwind`
|
||||||
#![deny(ffi_unwind_calls)]
|
#![deny(ffi_unwind_calls)]
|
||||||
// std may use features in a platform-specific way
|
// std may use features in a platform-specific way
|
||||||
@ -598,7 +599,7 @@ mod panicking;
|
|||||||
mod personality;
|
mod personality;
|
||||||
|
|
||||||
#[path = "../../backtrace/src/lib.rs"]
|
#[path = "../../backtrace/src/lib.rs"]
|
||||||
#[allow(dead_code, unused_attributes)]
|
#[allow(dead_code, unused_attributes, fuzzy_provenance_casts)]
|
||||||
mod backtrace_rs;
|
mod backtrace_rs;
|
||||||
|
|
||||||
// Re-export macros defined in libcore.
|
// Re-export macros defined in libcore.
|
||||||
|
@ -90,6 +90,7 @@ impl OwnedSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(strict_provenance_magic): we defined RawSocket to be a u64 ;-;
|
// FIXME(strict_provenance_magic): we defined RawSocket to be a u64 ;-;
|
||||||
|
#[allow(fuzzy_provenance_casts)]
|
||||||
#[cfg(not(target_vendor = "uwp"))]
|
#[cfg(not(target_vendor = "uwp"))]
|
||||||
pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
|
pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
|
||||||
cvt(unsafe {
|
cvt(unsafe {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
use super::DwarfReader;
|
use super::DwarfReader;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
use core::ptr;
|
||||||
|
|
||||||
pub const DW_EH_PE_omit: u8 = 0xFF;
|
pub const DW_EH_PE_omit: u8 = 0xFF;
|
||||||
pub const DW_EH_PE_absptr: u8 = 0x00;
|
pub const DW_EH_PE_absptr: u8 = 0x00;
|
||||||
@ -151,7 +152,7 @@ unsafe fn read_encoded_pointer(
|
|||||||
|
|
||||||
// DW_EH_PE_aligned implies it's an absolute pointer value
|
// DW_EH_PE_aligned implies it's an absolute pointer value
|
||||||
if encoding == DW_EH_PE_aligned {
|
if encoding == DW_EH_PE_aligned {
|
||||||
reader.ptr = round_up(reader.ptr as usize, mem::size_of::<usize>())? as *const u8;
|
reader.ptr = reader.ptr.with_addr(round_up(reader.ptr.addr(), mem::size_of::<usize>())?);
|
||||||
return Ok(reader.read::<usize>());
|
return Ok(reader.read::<usize>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +172,7 @@ unsafe fn read_encoded_pointer(
|
|||||||
result += match encoding & 0x70 {
|
result += match encoding & 0x70 {
|
||||||
DW_EH_PE_absptr => 0,
|
DW_EH_PE_absptr => 0,
|
||||||
// relative to address of the encoded value, despite the name
|
// relative to address of the encoded value, despite the name
|
||||||
DW_EH_PE_pcrel => reader.ptr as usize,
|
DW_EH_PE_pcrel => reader.ptr.expose_addr(),
|
||||||
DW_EH_PE_funcrel => {
|
DW_EH_PE_funcrel => {
|
||||||
if context.func_start == 0 {
|
if context.func_start == 0 {
|
||||||
return Err(());
|
return Err(());
|
||||||
@ -184,7 +185,7 @@ unsafe fn read_encoded_pointer(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if encoding & DW_EH_PE_indirect != 0 {
|
if encoding & DW_EH_PE_indirect != 0 {
|
||||||
result = *(result as *const usize);
|
result = *ptr::from_exposed_addr::<usize>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
//! This module contains the facade (aka platform-specific) implementations of
|
//! This module contains the facade (aka platform-specific) implementations of
|
||||||
//! OS level functionality for Fortanix SGX.
|
//! OS level functionality for Fortanix SGX.
|
||||||
#![deny(unsafe_op_in_unsafe_fn)]
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
#![allow(fuzzy_provenance_casts)] // FIXME: this entire module systematically confuses pointers and integers
|
||||||
|
|
||||||
use crate::io::ErrorKind;
|
use crate::io::ErrorKind;
|
||||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
use crate::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
@ -225,13 +225,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fd-lock"
|
name = "fd-lock"
|
||||||
version = "3.0.7"
|
version = "3.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c93a581058d957dc4176875aad04f82f81613e6611d64aa1a9c755bdfb16711"
|
checksum = "bb21c69b9fea5e15dbc1049e4b77145dd0ba1c84019c488102de0dc4ea4b0a27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys 0.42.0",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -319,9 +319,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "io-lifetimes"
|
name = "io-lifetimes"
|
||||||
version = "0.7.2"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24c3f4eff5495aee4c0399d7b6a0dc2b6e81be84242ffbfcf253ebacccc1d0cb"
|
checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
@ -337,15 +341,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.126"
|
version = "0.2.137"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.0.46"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d"
|
checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
@ -529,16 +533,16 @@ checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.35.6"
|
version = "0.36.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef258c11e17f5c01979a10543a30a4e12faef6aab217a74266e747eefa3aed88"
|
checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"errno",
|
"errno",
|
||||||
"io-lifetimes",
|
"io-lifetimes",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.36.1",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -725,19 +729,6 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_msvc 0.36.1",
|
|
||||||
"windows_i686_gnu 0.36.1",
|
|
||||||
"windows_i686_msvc 0.36.1",
|
|
||||||
"windows_x86_64_gnu 0.36.1",
|
|
||||||
"windows_x86_64_msvc 0.36.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.42.0"
|
version = "0.42.0"
|
||||||
@ -745,12 +736,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm",
|
"windows_aarch64_gnullvm",
|
||||||
"windows_aarch64_msvc 0.42.0",
|
"windows_aarch64_msvc",
|
||||||
"windows_i686_gnu 0.42.0",
|
"windows_i686_gnu",
|
||||||
"windows_i686_msvc 0.42.0",
|
"windows_i686_msvc",
|
||||||
"windows_x86_64_gnu 0.42.0",
|
"windows_x86_64_gnu",
|
||||||
"windows_x86_64_gnullvm",
|
"windows_x86_64_gnullvm",
|
||||||
"windows_x86_64_msvc 0.42.0",
|
"windows_x86_64_msvc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -759,48 +750,24 @@ version = "0.42.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
|
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.42.0"
|
version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
|
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.42.0"
|
version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
|
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.42.0"
|
version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
|
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.42.0"
|
version = "0.42.0"
|
||||||
@ -813,12 +780,6 @@ version = "0.42.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
|
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.42.0"
|
version = "0.42.0"
|
||||||
|
@ -36,7 +36,7 @@ test = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cmake = "0.1.38"
|
cmake = "0.1.38"
|
||||||
fd-lock = "3.0.7"
|
fd-lock = "3.0.8"
|
||||||
filetime = "0.2"
|
filetime = "0.2"
|
||||||
getopts = "0.2.19"
|
getopts = "0.2.19"
|
||||||
cc = "1.0.69"
|
cc = "1.0.69"
|
||||||
|
@ -318,6 +318,7 @@ pub(crate) fn clean_predicate<'tcx>(
|
|||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"),
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ fn defining_use() -> OpaqueClosure {
|
|||||||
struct Wrapper<T>(T);
|
struct Wrapper<T>(T);
|
||||||
trait Trait {}
|
trait Trait {}
|
||||||
impl Trait for Wrapper<OpaqueClosure> {}
|
impl Trait for Wrapper<OpaqueClosure> {}
|
||||||
//~^ ERROR cannot implement trait on type alias impl trait
|
|
||||||
impl<T: Sync> Trait for Wrapper<T> {}
|
impl<T: Sync> Trait for Wrapper<T> {}
|
||||||
//~^ ERROR conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
|
//~^ ERROR conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
|
||||||
|
|
||||||
|
@ -1,24 +1,11 @@
|
|||||||
error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
|
error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
|
||||||
--> $DIR/coherence-with-closure.rs:12:1
|
--> $DIR/coherence-with-closure.rs:11:1
|
||||||
|
|
|
|
||||||
LL | impl Trait for Wrapper<OpaqueClosure> {}
|
LL | impl Trait for Wrapper<OpaqueClosure> {}
|
||||||
| ------------------------------------- first implementation here
|
| ------------------------------------- first implementation here
|
||||||
LL |
|
|
||||||
LL | impl<T: Sync> Trait for Wrapper<T> {}
|
LL | impl<T: Sync> Trait for Wrapper<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>`
|
||||||
|
|
||||||
error: cannot implement trait on type alias impl trait
|
error: aborting due to previous error
|
||||||
--> $DIR/coherence-with-closure.rs:10:24
|
|
||||||
|
|
|
||||||
LL | impl Trait for Wrapper<OpaqueClosure> {}
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: type alias impl trait defined here
|
|
||||||
--> $DIR/coherence-with-closure.rs:3:22
|
|
||||||
|
|
|
||||||
LL | type OpaqueClosure = impl Sized;
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0119`.
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
|
@ -12,7 +12,6 @@ fn defining_use() -> OpaqueGenerator {
|
|||||||
struct Wrapper<T>(T);
|
struct Wrapper<T>(T);
|
||||||
trait Trait {}
|
trait Trait {}
|
||||||
impl Trait for Wrapper<OpaqueGenerator> {}
|
impl Trait for Wrapper<OpaqueGenerator> {}
|
||||||
//~^ ERROR cannot implement trait on type alias impl trait
|
|
||||||
impl<T: Sync> Trait for Wrapper<T> {}
|
impl<T: Sync> Trait for Wrapper<T> {}
|
||||||
//~^ ERROR conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
|
//~^ ERROR conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
|
||||||
|
|
||||||
|
@ -1,24 +1,11 @@
|
|||||||
error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
|
error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
|
||||||
--> $DIR/coherence-with-generator.rs:16:1
|
--> $DIR/coherence-with-generator.rs:15:1
|
||||||
|
|
|
|
||||||
LL | impl Trait for Wrapper<OpaqueGenerator> {}
|
LL | impl Trait for Wrapper<OpaqueGenerator> {}
|
||||||
| --------------------------------------- first implementation here
|
| --------------------------------------- first implementation here
|
||||||
LL |
|
|
||||||
LL | impl<T: Sync> Trait for Wrapper<T> {}
|
LL | impl<T: Sync> Trait for Wrapper<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>`
|
||||||
|
|
||||||
error: cannot implement trait on type alias impl trait
|
error: aborting due to previous error
|
||||||
--> $DIR/coherence-with-generator.rs:14:24
|
|
||||||
|
|
|
||||||
LL | impl Trait for Wrapper<OpaqueGenerator> {}
|
|
||||||
| ^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: type alias impl trait defined here
|
|
||||||
--> $DIR/coherence-with-generator.rs:3:24
|
|
||||||
|
|
|
||||||
LL | type OpaqueGenerator = impl Sized;
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0119`.
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
|
8
src/test/ui/errors/issue-104621-extern-bad-file.rs
Normal file
8
src/test/ui/errors/issue-104621-extern-bad-file.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// compile-flags: --extern foo={{src-base}}/errors/issue-104621-extern-bad-file.rs
|
||||||
|
// only-linux
|
||||||
|
|
||||||
|
extern crate foo;
|
||||||
|
//~^ ERROR extern location for foo is of an unknown type
|
||||||
|
//~| ERROR file name should be lib*.rlib or lib*.so
|
||||||
|
//~| ERROR can't find crate for `foo` [E0463]
|
||||||
|
fn main() {}
|
21
src/test/ui/errors/issue-104621-extern-bad-file.stderr
Normal file
21
src/test/ui/errors/issue-104621-extern-bad-file.stderr
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
error: extern location for foo is of an unknown type: $DIR/issue-104621-extern-bad-file.rs
|
||||||
|
--> $DIR/issue-104621-extern-bad-file.rs:4:1
|
||||||
|
|
|
||||||
|
LL | extern crate foo;
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: file name should be lib*.rlib or lib*.so
|
||||||
|
--> $DIR/issue-104621-extern-bad-file.rs:4:1
|
||||||
|
|
|
||||||
|
LL | extern crate foo;
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0463]: can't find crate for `foo`
|
||||||
|
--> $DIR/issue-104621-extern-bad-file.rs:4:1
|
||||||
|
|
|
||||||
|
LL | extern crate foo;
|
||||||
|
| ^^^^^^^^^^^^^^^^^ can't find crate
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0463`.
|
4
src/test/ui/errors/issue-104621-extern-not-file.rs
Normal file
4
src/test/ui/errors/issue-104621-extern-not-file.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// compile-flags: --extern foo=.
|
||||||
|
|
||||||
|
extern crate foo; //~ ERROR extern location for foo is not a file: .
|
||||||
|
fn main() {}
|
8
src/test/ui/errors/issue-104621-extern-not-file.stderr
Normal file
8
src/test/ui/errors/issue-104621-extern-not-file.stderr
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
error: extern location for foo is not a file: .
|
||||||
|
--> $DIR/issue-104621-extern-not-file.rs:3:1
|
||||||
|
|
|
||||||
|
LL | extern crate foo;
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
@ -20,7 +20,6 @@ impl<T: Send> AnotherTrait for T {}
|
|||||||
// in the future.)
|
// in the future.)
|
||||||
impl AnotherTrait for D<OpaqueType> {
|
impl AnotherTrait for D<OpaqueType> {
|
||||||
//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
|
//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
|
||||||
//~| ERROR cannot implement trait on type alias impl trait
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -7,18 +7,6 @@ LL | impl<T: Send> AnotherTrait for T {}
|
|||||||
LL | impl AnotherTrait for D<OpaqueType> {
|
LL | impl AnotherTrait for D<OpaqueType> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
|
||||||
|
|
||||||
error: cannot implement trait on type alias impl trait
|
error: aborting due to previous error
|
||||||
--> $DIR/auto-trait.rs:21:25
|
|
||||||
|
|
|
||||||
LL | impl AnotherTrait for D<OpaqueType> {
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: type alias impl trait defined here
|
|
||||||
--> $DIR/auto-trait.rs:7:19
|
|
||||||
|
|
|
||||||
LL | type OpaqueType = impl OpaqueTrait;
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0119`.
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
|
@ -18,7 +18,6 @@ impl<T: std::fmt::Debug> AnotherTrait for T {}
|
|||||||
// This is in error, because we cannot assume that `OpaqueType: !Debug`
|
// This is in error, because we cannot assume that `OpaqueType: !Debug`
|
||||||
impl AnotherTrait for D<OpaqueType> {
|
impl AnotherTrait for D<OpaqueType> {
|
||||||
//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
|
//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
|
||||||
//~| ERROR cannot implement trait on type alias impl trait
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -9,18 +9,6 @@ LL | impl AnotherTrait for D<OpaqueType> {
|
|||||||
|
|
|
|
||||||
= note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
|
= note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
|
||||||
|
|
||||||
error: cannot implement trait on type alias impl trait
|
error: aborting due to previous error
|
||||||
--> $DIR/negative-reasoning.rs:19:25
|
|
||||||
|
|
|
||||||
LL | impl AnotherTrait for D<OpaqueType> {
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: type alias impl trait defined here
|
|
||||||
--> $DIR/negative-reasoning.rs:7:19
|
|
||||||
|
|
|
||||||
LL | type OpaqueType = impl OpaqueTrait;
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0119`.
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
|
@ -5,13 +5,13 @@ type Foo = impl PartialEq<(Foo, i32)>;
|
|||||||
struct Bar;
|
struct Bar;
|
||||||
|
|
||||||
impl PartialEq<(Foo, i32)> for Bar {
|
impl PartialEq<(Foo, i32)> for Bar {
|
||||||
//~^ ERROR cannot implement trait on type alias impl trait
|
|
||||||
fn eq(&self, _other: &(Foo, i32)) -> bool {
|
fn eq(&self, _other: &(Foo, i32)) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo() -> Foo {
|
fn foo() -> Foo {
|
||||||
|
//~^ ERROR can't compare `Bar` with `(Bar, i32)`
|
||||||
Bar
|
Bar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
error: cannot implement trait on type alias impl trait
|
error[E0277]: can't compare `Bar` with `(Bar, i32)`
|
||||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:7:17
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:13:13
|
||||||
|
|
|
|
||||||
LL | impl PartialEq<(Foo, i32)> for Bar {
|
LL | fn foo() -> Foo {
|
||||||
| ^^^
|
| ^^^ no implementation for `Bar == (Bar, i32)`
|
||||||
|
LL |
|
||||||
|
LL | Bar
|
||||||
|
| --- return type was inferred to be `Bar` here
|
||||||
|
|
|
|
||||||
note: type alias impl trait defined here
|
= help: the trait `PartialEq<(Bar, i32)>` is not implemented for `Bar`
|
||||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:3:12
|
= help: the trait `PartialEq<(Foo, i32)>` is implemented for `Bar`
|
||||||
|
|
|
||||||
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
mod a {
|
mod a {
|
||||||
type Foo = impl PartialEq<(Foo, i32)>;
|
type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
|
//~^ ERROR: unconstrained opaque type
|
||||||
|
|
||||||
struct Bar;
|
struct Bar;
|
||||||
|
|
||||||
impl PartialEq<(Bar, i32)> for Bar {
|
impl PartialEq<(Bar, i32)> for Bar {
|
||||||
fn eq(&self, _other: &(Foo, i32)) -> bool {
|
fn eq(&self, _other: &(Foo, i32)) -> bool {
|
||||||
|
//~^ ERROR: `eq` has an incompatible type for trait
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14,12 +16,13 @@ mod a {
|
|||||||
|
|
||||||
mod b {
|
mod b {
|
||||||
type Foo = impl PartialEq<(Foo, i32)>;
|
type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
|
//~^ ERROR: unconstrained opaque type
|
||||||
|
|
||||||
struct Bar;
|
struct Bar;
|
||||||
|
|
||||||
impl PartialEq<(Foo, i32)> for Bar {
|
impl PartialEq<(Foo, i32)> for Bar {
|
||||||
//~^ ERROR cannot implement trait on type alias impl trait
|
|
||||||
fn eq(&self, _other: &(Bar, i32)) -> bool {
|
fn eq(&self, _other: &(Bar, i32)) -> bool {
|
||||||
|
//~^ ERROR: `eq` has an incompatible type for trait
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,49 @@
|
|||||||
error: cannot implement trait on type alias impl trait
|
error: unconstrained opaque type
|
||||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:20:21
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
||||||
|
|
|
||||||
LL | impl PartialEq<(Foo, i32)> for Bar {
|
|
||||||
| ^^^
|
|
||||||
|
|
|
||||||
note: type alias impl trait defined here
|
|
||||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:16:16
|
|
||||||
|
|
|
|
||||||
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `Foo` must be used in combination with a concrete type within the same module
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0053]: method `eq` has an incompatible type for trait
|
||||||
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:30
|
||||||
|
|
|
||||||
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
|
| -------------------------- the found opaque type
|
||||||
|
...
|
||||||
|
LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| expected struct `a::Bar`, found opaque type
|
||||||
|
| help: change the parameter type to match the trait: `&(a::Bar, i32)`
|
||||||
|
|
|
||||||
|
= note: expected fn pointer `fn(&a::Bar, &(a::Bar, i32)) -> _`
|
||||||
|
found fn pointer `fn(&a::Bar, &(a::Foo, i32)) -> _`
|
||||||
|
|
||||||
|
error: unconstrained opaque type
|
||||||
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
|
||||||
|
|
|
||||||
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `Foo` must be used in combination with a concrete type within the same module
|
||||||
|
|
||||||
|
error[E0053]: method `eq` has an incompatible type for trait
|
||||||
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:30
|
||||||
|
|
|
||||||
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
|
| -------------------------- the expected opaque type
|
||||||
|
...
|
||||||
|
LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| expected opaque type, found struct `b::Bar`
|
||||||
|
| help: change the parameter type to match the trait: `&(b::Foo, i32)`
|
||||||
|
|
|
||||||
|
= note: expected fn pointer `fn(&b::Bar, &(b::Foo, i32)) -> _`
|
||||||
|
found fn pointer `fn(&b::Bar, &(b::Bar, i32)) -> _`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0053`.
|
||||||
|
@ -3,12 +3,18 @@
|
|||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
#![warn(unused_must_use)]
|
#![warn(unused_must_use)]
|
||||||
|
#![feature(never_type)]
|
||||||
|
|
||||||
|
fn deref_never(x: &!) {
|
||||||
|
// Don't lint for uninhabited typess
|
||||||
|
*x;
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let val = 1;
|
let val = 1;
|
||||||
let val_pointer = &val;
|
let val_pointer = &val;
|
||||||
|
|
||||||
// Comparison Operators
|
// Comparison Operators
|
||||||
val == 1; //~ WARNING unused comparison
|
val == 1; //~ WARNING unused comparison
|
||||||
val < 1; //~ WARNING unused comparison
|
val < 1; //~ WARNING unused comparison
|
||||||
val <= 1; //~ WARNING unused comparison
|
val <= 1; //~ WARNING unused comparison
|
||||||
@ -16,26 +22,30 @@ fn main() {
|
|||||||
val >= 1; //~ WARNING unused comparison
|
val >= 1; //~ WARNING unused comparison
|
||||||
val > 1; //~ WARNING unused comparison
|
val > 1; //~ WARNING unused comparison
|
||||||
|
|
||||||
// Arithmetic Operators
|
// Arithmetic Operators
|
||||||
val + 2; //~ WARNING unused arithmetic operation
|
val + 2; //~ WARNING unused arithmetic operation
|
||||||
val - 2; //~ WARNING unused arithmetic operation
|
val - 2; //~ WARNING unused arithmetic operation
|
||||||
val / 2; //~ WARNING unused arithmetic operation
|
val / 2; //~ WARNING unused arithmetic operation
|
||||||
val * 2; //~ WARNING unused arithmetic operation
|
val * 2; //~ WARNING unused arithmetic operation
|
||||||
val % 2; //~ WARNING unused arithmetic operation
|
val % 2; //~ WARNING unused arithmetic operation
|
||||||
|
|
||||||
// Logical Operators
|
// Logical Operators
|
||||||
true && true; //~ WARNING unused logical operation
|
true && true; //~ WARNING unused logical operation
|
||||||
false || true; //~ WARNING unused logical operation
|
false || true; //~ WARNING unused logical operation
|
||||||
|
|
||||||
// Bitwise Operators
|
// Bitwise Operators
|
||||||
5 ^ val; //~ WARNING unused bitwise operation
|
5 ^ val; //~ WARNING unused bitwise operation
|
||||||
5 & val; //~ WARNING unused bitwise operation
|
5 & val; //~ WARNING unused bitwise operation
|
||||||
5 | val; //~ WARNING unused bitwise operation
|
5 | val; //~ WARNING unused bitwise operation
|
||||||
5 << val; //~ WARNING unused bitwise operation
|
5 << val; //~ WARNING unused bitwise operation
|
||||||
5 >> val; //~ WARNING unused bitwise operation
|
5 >> val; //~ WARNING unused bitwise operation
|
||||||
|
|
||||||
// Unary Operators
|
// Unary Operators
|
||||||
!val; //~ WARNING unused unary operation
|
!val; //~ WARNING unused unary operation
|
||||||
-val; //~ WARNING unused unary operation
|
-val; //~ WARNING unused unary operation
|
||||||
*val_pointer; //~ WARNING unused unary operation
|
*val_pointer; //~ WARNING unused unary operation
|
||||||
|
|
||||||
|
if false {
|
||||||
|
deref_never(&panic!());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
warning: unused comparison that must be used
|
warning: unused comparison that must be used
|
||||||
--> $DIR/must-use-ops.rs:12:5
|
--> $DIR/must-use-ops.rs:18:5
|
||||||
|
|
|
|
||||||
LL | val == 1;
|
LL | val == 1;
|
||||||
| ^^^^^^^^ the comparison produces a value
|
| ^^^^^^^^ the comparison produces a value
|
||||||
@ -15,7 +15,7 @@ LL | let _ = val == 1;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused comparison that must be used
|
warning: unused comparison that must be used
|
||||||
--> $DIR/must-use-ops.rs:13:5
|
--> $DIR/must-use-ops.rs:19:5
|
||||||
|
|
|
|
||||||
LL | val < 1;
|
LL | val < 1;
|
||||||
| ^^^^^^^ the comparison produces a value
|
| ^^^^^^^ the comparison produces a value
|
||||||
@ -26,7 +26,7 @@ LL | let _ = val < 1;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused comparison that must be used
|
warning: unused comparison that must be used
|
||||||
--> $DIR/must-use-ops.rs:14:5
|
--> $DIR/must-use-ops.rs:20:5
|
||||||
|
|
|
|
||||||
LL | val <= 1;
|
LL | val <= 1;
|
||||||
| ^^^^^^^^ the comparison produces a value
|
| ^^^^^^^^ the comparison produces a value
|
||||||
@ -37,7 +37,7 @@ LL | let _ = val <= 1;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused comparison that must be used
|
warning: unused comparison that must be used
|
||||||
--> $DIR/must-use-ops.rs:15:5
|
--> $DIR/must-use-ops.rs:21:5
|
||||||
|
|
|
|
||||||
LL | val != 1;
|
LL | val != 1;
|
||||||
| ^^^^^^^^ the comparison produces a value
|
| ^^^^^^^^ the comparison produces a value
|
||||||
@ -48,7 +48,7 @@ LL | let _ = val != 1;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused comparison that must be used
|
warning: unused comparison that must be used
|
||||||
--> $DIR/must-use-ops.rs:16:5
|
--> $DIR/must-use-ops.rs:22:5
|
||||||
|
|
|
|
||||||
LL | val >= 1;
|
LL | val >= 1;
|
||||||
| ^^^^^^^^ the comparison produces a value
|
| ^^^^^^^^ the comparison produces a value
|
||||||
@ -59,7 +59,7 @@ LL | let _ = val >= 1;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused comparison that must be used
|
warning: unused comparison that must be used
|
||||||
--> $DIR/must-use-ops.rs:17:5
|
--> $DIR/must-use-ops.rs:23:5
|
||||||
|
|
|
|
||||||
LL | val > 1;
|
LL | val > 1;
|
||||||
| ^^^^^^^ the comparison produces a value
|
| ^^^^^^^ the comparison produces a value
|
||||||
@ -70,7 +70,7 @@ LL | let _ = val > 1;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused arithmetic operation that must be used
|
warning: unused arithmetic operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:20:5
|
--> $DIR/must-use-ops.rs:26:5
|
||||||
|
|
|
|
||||||
LL | val + 2;
|
LL | val + 2;
|
||||||
| ^^^^^^^ the arithmetic operation produces a value
|
| ^^^^^^^ the arithmetic operation produces a value
|
||||||
@ -81,7 +81,7 @@ LL | let _ = val + 2;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused arithmetic operation that must be used
|
warning: unused arithmetic operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:21:5
|
--> $DIR/must-use-ops.rs:27:5
|
||||||
|
|
|
|
||||||
LL | val - 2;
|
LL | val - 2;
|
||||||
| ^^^^^^^ the arithmetic operation produces a value
|
| ^^^^^^^ the arithmetic operation produces a value
|
||||||
@ -92,7 +92,7 @@ LL | let _ = val - 2;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused arithmetic operation that must be used
|
warning: unused arithmetic operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:22:5
|
--> $DIR/must-use-ops.rs:28:5
|
||||||
|
|
|
|
||||||
LL | val / 2;
|
LL | val / 2;
|
||||||
| ^^^^^^^ the arithmetic operation produces a value
|
| ^^^^^^^ the arithmetic operation produces a value
|
||||||
@ -103,7 +103,7 @@ LL | let _ = val / 2;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused arithmetic operation that must be used
|
warning: unused arithmetic operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:23:5
|
--> $DIR/must-use-ops.rs:29:5
|
||||||
|
|
|
|
||||||
LL | val * 2;
|
LL | val * 2;
|
||||||
| ^^^^^^^ the arithmetic operation produces a value
|
| ^^^^^^^ the arithmetic operation produces a value
|
||||||
@ -114,7 +114,7 @@ LL | let _ = val * 2;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused arithmetic operation that must be used
|
warning: unused arithmetic operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:24:5
|
--> $DIR/must-use-ops.rs:30:5
|
||||||
|
|
|
|
||||||
LL | val % 2;
|
LL | val % 2;
|
||||||
| ^^^^^^^ the arithmetic operation produces a value
|
| ^^^^^^^ the arithmetic operation produces a value
|
||||||
@ -125,7 +125,7 @@ LL | let _ = val % 2;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused logical operation that must be used
|
warning: unused logical operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:27:5
|
--> $DIR/must-use-ops.rs:33:5
|
||||||
|
|
|
|
||||||
LL | true && true;
|
LL | true && true;
|
||||||
| ^^^^^^^^^^^^ the logical operation produces a value
|
| ^^^^^^^^^^^^ the logical operation produces a value
|
||||||
@ -136,7 +136,7 @@ LL | let _ = true && true;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused logical operation that must be used
|
warning: unused logical operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:28:5
|
--> $DIR/must-use-ops.rs:34:5
|
||||||
|
|
|
|
||||||
LL | false || true;
|
LL | false || true;
|
||||||
| ^^^^^^^^^^^^^ the logical operation produces a value
|
| ^^^^^^^^^^^^^ the logical operation produces a value
|
||||||
@ -147,7 +147,7 @@ LL | let _ = false || true;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused bitwise operation that must be used
|
warning: unused bitwise operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:31:5
|
--> $DIR/must-use-ops.rs:37:5
|
||||||
|
|
|
|
||||||
LL | 5 ^ val;
|
LL | 5 ^ val;
|
||||||
| ^^^^^^^ the bitwise operation produces a value
|
| ^^^^^^^ the bitwise operation produces a value
|
||||||
@ -158,7 +158,7 @@ LL | let _ = 5 ^ val;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused bitwise operation that must be used
|
warning: unused bitwise operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:32:5
|
--> $DIR/must-use-ops.rs:38:5
|
||||||
|
|
|
|
||||||
LL | 5 & val;
|
LL | 5 & val;
|
||||||
| ^^^^^^^ the bitwise operation produces a value
|
| ^^^^^^^ the bitwise operation produces a value
|
||||||
@ -169,7 +169,7 @@ LL | let _ = 5 & val;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused bitwise operation that must be used
|
warning: unused bitwise operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:33:5
|
--> $DIR/must-use-ops.rs:39:5
|
||||||
|
|
|
|
||||||
LL | 5 | val;
|
LL | 5 | val;
|
||||||
| ^^^^^^^ the bitwise operation produces a value
|
| ^^^^^^^ the bitwise operation produces a value
|
||||||
@ -180,7 +180,7 @@ LL | let _ = 5 | val;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused bitwise operation that must be used
|
warning: unused bitwise operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:34:5
|
--> $DIR/must-use-ops.rs:40:5
|
||||||
|
|
|
|
||||||
LL | 5 << val;
|
LL | 5 << val;
|
||||||
| ^^^^^^^^ the bitwise operation produces a value
|
| ^^^^^^^^ the bitwise operation produces a value
|
||||||
@ -191,7 +191,7 @@ LL | let _ = 5 << val;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused bitwise operation that must be used
|
warning: unused bitwise operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:35:5
|
--> $DIR/must-use-ops.rs:41:5
|
||||||
|
|
|
|
||||||
LL | 5 >> val;
|
LL | 5 >> val;
|
||||||
| ^^^^^^^^ the bitwise operation produces a value
|
| ^^^^^^^^ the bitwise operation produces a value
|
||||||
@ -202,7 +202,7 @@ LL | let _ = 5 >> val;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused unary operation that must be used
|
warning: unused unary operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:38:5
|
--> $DIR/must-use-ops.rs:44:5
|
||||||
|
|
|
|
||||||
LL | !val;
|
LL | !val;
|
||||||
| ^^^^ the unary operation produces a value
|
| ^^^^ the unary operation produces a value
|
||||||
@ -213,7 +213,7 @@ LL | let _ = !val;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused unary operation that must be used
|
warning: unused unary operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:39:5
|
--> $DIR/must-use-ops.rs:45:5
|
||||||
|
|
|
|
||||||
LL | -val;
|
LL | -val;
|
||||||
| ^^^^ the unary operation produces a value
|
| ^^^^ the unary operation produces a value
|
||||||
@ -224,7 +224,7 @@ LL | let _ = -val;
|
|||||||
| +++++++
|
| +++++++
|
||||||
|
|
||||||
warning: unused unary operation that must be used
|
warning: unused unary operation that must be used
|
||||||
--> $DIR/must-use-ops.rs:40:5
|
--> $DIR/must-use-ops.rs:46:5
|
||||||
|
|
|
|
||||||
LL | *val_pointer;
|
LL | *val_pointer;
|
||||||
| ^^^^^^^^^^^^ the unary operation produces a value
|
| ^^^^^^^^^^^^ the unary operation produces a value
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#![deny(unused_must_use)]
|
#![deny(unused_must_use)]
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
struct S;
|
struct S;
|
||||||
|
|
||||||
struct A;
|
struct A;
|
||||||
@ -34,6 +35,10 @@ fn array_of_arrays_of_arrays() -> [[[S; 1]; 2]; 1] {
|
|||||||
[[[S], [S]]]
|
[[[S], [S]]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn usize_max() -> [S; usize::MAX] {
|
||||||
|
[S; usize::MAX]
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
empty(); // ok
|
empty(); // ok
|
||||||
singleton(); //~ ERROR unused array of `S` that must be used
|
singleton(); //~ ERROR unused array of `S` that must be used
|
||||||
@ -44,4 +49,6 @@ fn main() {
|
|||||||
//~^ ERROR unused array of boxed `T` trait objects in tuple element 1 that must be used
|
//~^ ERROR unused array of boxed `T` trait objects in tuple element 1 that must be used
|
||||||
array_of_arrays_of_arrays();
|
array_of_arrays_of_arrays();
|
||||||
//~^ ERROR unused array of arrays of arrays of `S` that must be used
|
//~^ ERROR unused array of arrays of arrays of `S` that must be used
|
||||||
|
usize_max();
|
||||||
|
//~^ ERROR unused array of `S` that must be used
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: unused array of `S` that must be used
|
error: unused array of `S` that must be used
|
||||||
--> $DIR/must_use-array.rs:39:5
|
--> $DIR/must_use-array.rs:44:5
|
||||||
|
|
|
|
||||||
LL | singleton();
|
LL | singleton();
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -11,34 +11,40 @@ LL | #![deny(unused_must_use)]
|
|||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: unused array of `S` that must be used
|
error: unused array of `S` that must be used
|
||||||
--> $DIR/must_use-array.rs:40:5
|
--> $DIR/must_use-array.rs:45:5
|
||||||
|
|
|
|
||||||
LL | many();
|
LL | many();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: unused array of `S` in tuple element 0 that must be used
|
error: unused array of `S` in tuple element 0 that must be used
|
||||||
--> $DIR/must_use-array.rs:41:6
|
--> $DIR/must_use-array.rs:46:6
|
||||||
|
|
|
|
||||||
LL | ([S], 0, ());
|
LL | ([S], 0, ());
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: unused array of implementers of `T` that must be used
|
error: unused array of implementers of `T` that must be used
|
||||||
--> $DIR/must_use-array.rs:42:5
|
--> $DIR/must_use-array.rs:47:5
|
||||||
|
|
|
|
||||||
LL | array_of_impl_trait();
|
LL | array_of_impl_trait();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: unused array of boxed `T` trait objects in tuple element 1 that must be used
|
error: unused array of boxed `T` trait objects in tuple element 1 that must be used
|
||||||
--> $DIR/must_use-array.rs:43:5
|
--> $DIR/must_use-array.rs:48:5
|
||||||
|
|
|
|
||||||
LL | impl_array();
|
LL | impl_array();
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error: unused array of arrays of arrays of `S` that must be used
|
error: unused array of arrays of arrays of `S` that must be used
|
||||||
--> $DIR/must_use-array.rs:45:5
|
--> $DIR/must_use-array.rs:50:5
|
||||||
|
|
|
|
||||||
LL | array_of_arrays_of_arrays();
|
LL | array_of_arrays_of_arrays();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: unused array of `S` that must be used
|
||||||
|
--> $DIR/must_use-array.rs:52:5
|
||||||
|
|
|
||||||
|
LL | usize_max();
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@ trait AnotherTrait {}
|
|||||||
impl<T: Send> AnotherTrait for T {}
|
impl<T: Send> AnotherTrait for T {}
|
||||||
impl AnotherTrait for OpaqueType {}
|
impl AnotherTrait for OpaqueType {}
|
||||||
//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
|
//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
|
||||||
//~| ERROR cannot implement trait on type alias impl trait
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -6,18 +6,6 @@ LL | impl<T: Send> AnotherTrait for T {}
|
|||||||
LL | impl AnotherTrait for OpaqueType {}
|
LL | impl AnotherTrait for OpaqueType {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
|
||||||
|
|
||||||
error: cannot implement trait on type alias impl trait
|
error: aborting due to previous error
|
||||||
--> $DIR/issue-83613.rs:10:23
|
|
||||||
|
|
|
||||||
LL | impl AnotherTrait for OpaqueType {}
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: type alias impl trait defined here
|
|
||||||
--> $DIR/issue-83613.rs:4:19
|
|
||||||
|
|
|
||||||
LL | type OpaqueType = impl OpaqueTrait;
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0119`.
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
|
@ -12,6 +12,6 @@ fn use_alias<T>(val: T) -> AliasOfForeignType<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
|
impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
|
||||||
//~^ ERROR cannot implement trait on type alias impl trait
|
//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
error: cannot implement trait on type alias impl trait
|
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
|
||||||
--> $DIR/coherence.rs:14:41
|
--> $DIR/coherence.rs:14:1
|
||||||
|
|
|
|
||||||
LL | impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
|
LL | impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------
|
||||||
|
| | |
|
||||||
|
| | `AliasOfForeignType<T>` is not defined in the current crate
|
||||||
|
| impl doesn't use only types from inside the current crate
|
||||||
|
|
|
|
||||||
note: type alias impl trait defined here
|
= note: define and implement a trait or new type instead
|
||||||
--> $DIR/coherence.rs:9:30
|
|
||||||
|
|
|
||||||
LL | type AliasOfForeignType<T> = impl LocalTrait;
|
|
||||||
| ^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0117`.
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
trait Trait {}
|
||||||
|
type Opaque<T> = impl Sized;
|
||||||
|
fn foo<T>() -> Opaque<T> {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, V> Trait for (T, V, V, u32) {}
|
||||||
|
impl<U, V> Trait for (Opaque<U>, V, i32, V) {}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,23 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
trait Foo {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for i32 {
|
||||||
|
type Assoc = u32;
|
||||||
|
}
|
||||||
|
type ImplTrait = impl Sized;
|
||||||
|
fn constrain() -> ImplTrait {
|
||||||
|
1u64
|
||||||
|
}
|
||||||
|
impl Foo for i64 {
|
||||||
|
type Assoc = ImplTrait;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Bar<T> {}
|
||||||
|
|
||||||
|
impl<T: Foo> Bar<<T as Foo>::Assoc> for T {}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,33 @@
|
|||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
trait Foo {}
|
||||||
|
impl Foo for () {}
|
||||||
|
impl Foo for i32 {}
|
||||||
|
|
||||||
|
type Bar<T: Foo> = impl std::fmt::Debug;
|
||||||
|
fn defining_use<T: Foo>() -> Bar<T> {
|
||||||
|
42
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Bop {}
|
||||||
|
|
||||||
|
impl Bop for Bar<()> {}
|
||||||
|
|
||||||
|
// If the hidden type is the same, this is effectively a second impl for the same type.
|
||||||
|
impl Bop for Bar<i32> {}
|
||||||
|
//~^ ERROR conflicting implementations
|
||||||
|
|
||||||
|
type Barr = impl std::fmt::Debug;
|
||||||
|
fn defining_use2() -> Barr {
|
||||||
|
42
|
||||||
|
}
|
||||||
|
|
||||||
|
// Even completely different opaque types must conflict.
|
||||||
|
impl Bop for Barr {}
|
||||||
|
//~^ ERROR conflicting implementations
|
||||||
|
|
||||||
|
// And obviously the hidden type must conflict, too.
|
||||||
|
impl Bop for i32 {}
|
||||||
|
//~^ ERROR conflicting implementations
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,30 @@
|
|||||||
|
error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
|
||||||
|
--> $DIR/impl_trait_for_same_tait.rs:17:1
|
||||||
|
|
|
||||||
|
LL | impl Bop for Bar<()> {}
|
||||||
|
| -------------------- first implementation here
|
||||||
|
...
|
||||||
|
LL | impl Bop for Bar<i32> {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
|
||||||
|
|
||||||
|
error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
|
||||||
|
--> $DIR/impl_trait_for_same_tait.rs:26:1
|
||||||
|
|
|
||||||
|
LL | impl Bop for Bar<()> {}
|
||||||
|
| -------------------- first implementation here
|
||||||
|
...
|
||||||
|
LL | impl Bop for Barr {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
|
||||||
|
|
||||||
|
error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
|
||||||
|
--> $DIR/impl_trait_for_same_tait.rs:30:1
|
||||||
|
|
|
||||||
|
LL | impl Bop for Bar<()> {}
|
||||||
|
| -------------------- first implementation here
|
||||||
|
...
|
||||||
|
LL | impl Bop for i32 {}
|
||||||
|
| ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0119`.
|
21
src/test/ui/type-alias-impl-trait/impl_trait_for_tait.rs
Normal file
21
src/test/ui/type-alias-impl-trait/impl_trait_for_tait.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// compile-flags: --crate-type=lib
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
type Alias = impl Sized;
|
||||||
|
|
||||||
|
fn constrain() -> Alias {
|
||||||
|
1i32
|
||||||
|
}
|
||||||
|
|
||||||
|
trait HideIt {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HideIt for () {
|
||||||
|
type Assoc = Alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Yay {}
|
||||||
|
|
||||||
|
impl Yay for <() as HideIt>::Assoc {}
|
@ -0,0 +1,19 @@
|
|||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
type Foo = impl Debug;
|
||||||
|
pub trait Yay { }
|
||||||
|
impl Yay for Foo { }
|
||||||
|
|
||||||
|
fn foo() {
|
||||||
|
is_yay::<u32>(); //~ ERROR: the trait bound `u32: Yay` is not satisfied
|
||||||
|
is_debug::<u32>(); // OK
|
||||||
|
is_yay::<Foo>(); // OK
|
||||||
|
is_debug::<Foo>(); // OK
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_yay<T: Yay>() { }
|
||||||
|
fn is_debug<T: Debug>() { }
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,16 @@
|
|||||||
|
error[E0277]: the trait bound `u32: Yay` is not satisfied
|
||||||
|
--> $DIR/impl_trait_for_tait_bound.rs:10:14
|
||||||
|
|
|
||||||
|
LL | is_yay::<u32>();
|
||||||
|
| ^^^ the trait `Yay` is not implemented for `u32`
|
||||||
|
|
|
||||||
|
= help: the trait `Yay` is implemented for `Foo`
|
||||||
|
note: required by a bound in `is_yay`
|
||||||
|
--> $DIR/impl_trait_for_tait_bound.rs:16:14
|
||||||
|
|
|
||||||
|
LL | fn is_yay<T: Yay>() { }
|
||||||
|
| ^^^ required by this bound in `is_yay`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
@ -0,0 +1,16 @@
|
|||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
type Foo = impl Debug;
|
||||||
|
|
||||||
|
pub trait Yay { }
|
||||||
|
impl Yay for u32 { }
|
||||||
|
|
||||||
|
fn foo() {
|
||||||
|
is_yay::<Foo>(); //~ ERROR: the trait bound `Foo: Yay` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_yay<T: Yay>() { }
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,16 @@
|
|||||||
|
error[E0277]: the trait bound `Foo: Yay` is not satisfied
|
||||||
|
--> $DIR/impl_trait_for_tait_bound2.rs:11:14
|
||||||
|
|
|
||||||
|
LL | is_yay::<Foo>();
|
||||||
|
| ^^^ the trait `Yay` is not implemented for `Foo`
|
||||||
|
|
|
||||||
|
= help: the trait `Yay` is implemented for `u32`
|
||||||
|
note: required by a bound in `is_yay`
|
||||||
|
--> $DIR/impl_trait_for_tait_bound2.rs:14:14
|
||||||
|
|
|
||||||
|
LL | fn is_yay<T: Yay>() { }
|
||||||
|
| ^^^ required by this bound in `is_yay`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
@ -8,7 +8,7 @@ impl MyTrait for () {}
|
|||||||
type Bar = impl MyTrait;
|
type Bar = impl MyTrait;
|
||||||
|
|
||||||
impl MyTrait for Bar {}
|
impl MyTrait for Bar {}
|
||||||
//~^ ERROR: cannot implement trait on type alias impl trait
|
//~^ ERROR: conflicting implementations of trait `MyTrait` for type `()`
|
||||||
|
|
||||||
fn bazr() -> Bar { }
|
fn bazr() -> Bar { }
|
||||||
|
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
error: cannot implement trait on type alias impl trait
|
error[E0119]: conflicting implementations of trait `MyTrait` for type `()`
|
||||||
--> $DIR/issue-65384.rs:10:18
|
--> $DIR/issue-65384.rs:10:1
|
||||||
|
|
|
|
||||||
|
LL | impl MyTrait for () {}
|
||||||
|
| ------------------- first implementation here
|
||||||
|
...
|
||||||
LL | impl MyTrait for Bar {}
|
LL | impl MyTrait for Bar {}
|
||||||
| ^^^
|
| ^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
|
||||||
|
|
|
||||||
note: type alias impl trait defined here
|
|
||||||
--> $DIR/issue-65384.rs:8:12
|
|
||||||
|
|
|
||||||
LL | type Bar = impl MyTrait;
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// Regression test for issue #76202
|
// Regression test for issue #76202
|
||||||
// Tests that we don't ICE when we have a trait impl on a TAIT.
|
// Tests that we don't ICE when we have a trait impl on a TAIT.
|
||||||
|
|
||||||
|
// check-pass
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
trait Dummy {}
|
trait Dummy {}
|
||||||
@ -14,7 +16,12 @@ trait Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Test for F {
|
impl Test for F {
|
||||||
//~^ ERROR cannot implement trait
|
fn test(self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok because `i32` does not implement `Dummy`,
|
||||||
|
// so it can't possibly be the hidden type of `F`.
|
||||||
|
impl Test for i32 {
|
||||||
fn test(self) {}
|
fn test(self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
error: cannot implement trait on type alias impl trait
|
|
||||||
--> $DIR/issue-76202-trait-impl-for-tait.rs:16:15
|
|
||||||
|
|
|
||||||
LL | impl Test for F {
|
|
||||||
| ^
|
|
||||||
|
|
|
||||||
note: type alias impl trait defined here
|
|
||||||
--> $DIR/issue-76202-trait-impl-for-tait.rs:9:10
|
|
||||||
|
|
|
||||||
LL | type F = impl Dummy;
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
|||||||
// Regression test for issues #84660 and #86411: both are variations on #76202.
|
// Regression test for issues #84660 and #86411: both are variations on #76202.
|
||||||
// Tests that we don't ICE when we have an opaque type appearing anywhere in an impl header.
|
// Tests that we don't ICE when we have an opaque type appearing anywhere in an impl header.
|
||||||
|
|
||||||
|
// check-pass
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
trait Foo {}
|
trait Foo {}
|
||||||
@ -12,7 +14,7 @@ trait TraitArg<T> {
|
|||||||
fn f();
|
fn f();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TraitArg<Bar> for () { //~ ERROR cannot implement trait
|
impl TraitArg<Bar> for () {
|
||||||
fn f() {
|
fn f() {
|
||||||
println!("ho");
|
println!("ho");
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
error: cannot implement trait on type alias impl trait
|
|
||||||
--> $DIR/issue-84660-trait-impl-for-tait.rs:15:15
|
|
||||||
|
|
|
||||||
LL | impl TraitArg<Bar> for () {
|
|
||||||
| ^^^
|
|
||||||
|
|
|
||||||
note: type alias impl trait defined here
|
|
||||||
--> $DIR/issue-84660-trait-impl-for-tait.rs:8:12
|
|
||||||
|
|
|
||||||
LL | type Bar = impl Foo;
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
@ -13,14 +13,14 @@ trait Trait<T, In> {
|
|||||||
fn convert(i: In) -> Self::Out;
|
fn convert(i: In) -> Self::Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<In, Out> Trait<Bar, In> for Out { //~ ERROR cannot implement trait
|
impl<In, Out> Trait<Bar, In> for Out {
|
||||||
type Out = Out;
|
type Out = Out;
|
||||||
fn convert(_i: In) -> Self::Out {
|
fn convert(_i: In) -> Self::Out {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<In, Out> Trait<(), In> for Out {
|
impl<In, Out> Trait<(), In> for Out { //~ ERROR conflicting implementations of trait `Trait<Bar, _>`
|
||||||
type Out = In;
|
type Out = In;
|
||||||
fn convert(i: In) -> Self::Out {
|
fn convert(i: In) -> Self::Out {
|
||||||
i
|
i
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
error: cannot implement trait on type alias impl trait
|
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
||||||
--> $DIR/issue-84660-unsoundness.rs:16:21
|
--> $DIR/issue-84660-unsoundness.rs:23:1
|
||||||
|
|
|
|
||||||
LL | impl<In, Out> Trait<Bar, In> for Out {
|
LL | impl<In, Out> Trait<Bar, In> for Out {
|
||||||
| ^^^
|
| ------------------------------------ first implementation here
|
||||||
|
|
...
|
||||||
note: type alias impl trait defined here
|
LL | impl<In, Out> Trait<(), In> for Out {
|
||||||
--> $DIR/issue-84660-unsoundness.rs:8:12
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
|
||||||
|
|
|
||||||
LL | type Bar = impl Foo;
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
type FooX = impl Debug;
|
type FooX = impl Debug;
|
||||||
|
//~^ ERROR unconstrained opaque type
|
||||||
|
|
||||||
trait Foo<A> { }
|
trait Foo<A> { }
|
||||||
|
|
||||||
impl Foo<FooX> for () { }
|
impl Foo<FooX> for () { }
|
||||||
//~^ cannot implement trait on type alias impl trait
|
|
||||||
|
|
||||||
fn foo() -> impl Foo<FooX> {
|
fn foo() -> impl Foo<FooX> {
|
||||||
()
|
()
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
error: cannot implement trait on type alias impl trait
|
error: unconstrained opaque type
|
||||||
--> $DIR/nested-tait-inference3.rs:10:10
|
|
||||||
|
|
|
||||||
LL | impl Foo<FooX> for () { }
|
|
||||||
| ^^^^
|
|
||||||
|
|
|
||||||
note: type alias impl trait defined here
|
|
||||||
--> $DIR/nested-tait-inference3.rs:6:13
|
--> $DIR/nested-tait-inference3.rs:6:13
|
||||||
|
|
|
|
||||||
LL | type FooX = impl Debug;
|
LL | type FooX = impl Debug;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `FooX` must be used in combination with a concrete type within the same module
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: Option<
|
|||||||
ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {predicate:#?}"),
|
ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {predicate:#?}"),
|
||||||
ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {predicate:#?}"),
|
ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {predicate:#?}"),
|
||||||
ty::PredicateKind::Coerce(_) => panic!("coerce predicate on function: {predicate:#?}"),
|
ty::PredicateKind::Coerce(_) => panic!("coerce predicate on function: {predicate:#?}"),
|
||||||
|
ty::PredicateKind::Ambiguous => panic!("ambiguous predicate on function: {predicate:#?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match predicates.parent {
|
match predicates.parent {
|
||||||
|
Loading…
Reference in New Issue
Block a user