diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index c864349019b88..7c83fe7fd6946 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -4,6 +4,7 @@ use super::combine::CombineFields; use super::{HigherRankedType, InferCtxt, PlaceholderMap}; +use crate::infer::CombinedSnapshot; use crate::ty::relate::{Relate, RelateResult, TypeRelation}; use crate::ty::{self, Binder, TypeFoldable}; @@ -29,27 +30,32 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { let span = self.trace.cause.span; - // First, we instantiate each bound region in the supertype with a - // fresh placeholder region. - let (b_prime, _) = self.infcx.replace_bound_vars_with_placeholders(b); + return self.infcx.commit_if_ok(|snapshot| { + // First, we instantiate each bound region in the supertype with a + // fresh placeholder region. + let (b_prime, placeholder_map) = self.infcx.replace_bound_vars_with_placeholders(b); - // Next, we instantiate each bound region in the subtype - // with a fresh region variable. These region variables -- - // but no other pre-existing region variables -- can name - // the placeholders. - let (a_prime, _) = - self.infcx - .replace_bound_vars_with_fresh_vars(span, HigherRankedType, a); + // Next, we instantiate each bound region in the subtype + // with a fresh region variable. These region variables -- + // but no other pre-existing region variables -- can name + // the placeholders. + let (a_prime, _) = + self.infcx + .replace_bound_vars_with_fresh_vars(span, HigherRankedType, a); + + debug!("a_prime={:?}", a_prime); + debug!("b_prime={:?}", b_prime); - debug!("a_prime={:?}", a_prime); - debug!("b_prime={:?}", b_prime); + // Compare types now that bound regions have been replaced. + let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?; - // Compare types now that bound regions have been replaced. - let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?; + self.infcx + .leak_check(!a_is_expected, &placeholder_map, snapshot)?; - debug!("higher_ranked_sub: OK result={:?}", result); + debug!("higher_ranked_sub: OK result={:?}", result); - Ok(ty::Binder::bind(result)) + Ok(ty::Binder::bind(result)) + }); } } @@ -72,10 +78,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html pub fn replace_bound_vars_with_placeholders( &self, - binder: &ty::Binder + binder: &ty::Binder, ) -> (T, PlaceholderMap<'tcx>) where - T: TypeFoldable<'tcx> + T: TypeFoldable<'tcx>, { let next_universe = self.create_next_universe(); @@ -97,16 +103,24 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { debug!( "replace_bound_vars_with_placeholders(\ - next_universe={:?}, \ - binder={:?}, \ - result={:?}, \ - map={:?})", - next_universe, - binder, - result, - map, + next_universe={:?}, \ + binder={:?}, \ + result={:?}, \ + map={:?})", + next_universe, binder, result, map, ); (result, map) } + + /// See `infer::region_constraints::RegionConstraintCollector::leak_check`. + pub fn leak_check( + &self, + overly_polymorphic: bool, + placeholder_map: &PlaceholderMap<'tcx>, + snapshot: &CombinedSnapshot<'_, 'tcx>, + ) -> RelateResult<'tcx, ()> { + self.borrow_region_constraints() + .leak_check(self.tcx, overly_polymorphic, placeholder_map, snapshot) + } } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 04d08c199802e..ac2ebece442c8 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -937,32 +937,41 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { return None; } - let ( - ty::SubtypePredicate { - a_is_expected, - a, - b, - }, - _, - ) = self.replace_bound_vars_with_placeholders(predicate); + Some(self.commit_if_ok(|snapshot| { + let ( + ty::SubtypePredicate { + a_is_expected, + a, + b, + }, + placeholder_map, + ) = self.replace_bound_vars_with_placeholders(predicate); - Some( - self.at(cause, param_env) - .sub_exp(a_is_expected, a, b) - .map(|ok| ok.unit()), - ) + let ok = self.at(cause, param_env) + .sub_exp(a_is_expected, a, b)?; + + self.leak_check(false, &placeholder_map, snapshot)?; + + Ok(ok.unit()) + })) } pub fn region_outlives_predicate( &self, cause: &traits::ObligationCause<'tcx>, predicate: &ty::PolyRegionOutlivesPredicate<'tcx>, - ) { - let (ty::OutlivesPredicate(r_a, r_b), _) = - self.replace_bound_vars_with_placeholders(predicate); - let origin = - SubregionOrigin::from_obligation_cause(cause, || RelateRegionParamBound(cause.span)); - self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` + ) -> UnitResult<'tcx> { + self.commit_if_ok(|snapshot| { + let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) = + self.replace_bound_vars_with_placeholders(predicate); + let origin = SubregionOrigin::from_obligation_cause( + cause, + || RelateRegionParamBound(cause.span), + ); + self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` + self.leak_check(false, &placeholder_map, snapshot)?; + Ok(()) + }) } pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid { diff --git a/src/librustc/infer/region_constraints/leak_check.rs b/src/librustc/infer/region_constraints/leak_check.rs new file mode 100644 index 0000000000000..8085258610d84 --- /dev/null +++ b/src/librustc/infer/region_constraints/leak_check.rs @@ -0,0 +1,174 @@ +use super::*; +use crate::infer::{CombinedSnapshot, PlaceholderMap}; +use crate::ty::error::TypeError; +use crate::ty::relate::RelateResult; + +impl<'tcx> RegionConstraintCollector<'tcx> { + /// Searches region constraints created since `snapshot` that + /// affect one of the placeholders in `placeholder_map`, returning + /// an error if any of the placeholders are related to another + /// placeholder or would have to escape into some parent universe + /// that cannot name them. + /// + /// This is a temporary backwards compatibility measure to try and + /// retain the older (arguably incorrect) behavior of the + /// compiler. + /// + /// NB. The use of snapshot here is mostly an efficiency thing -- + /// we could search *all* region constraints, but that'd be a + /// bigger set and the data structures are not setup for that. If + /// we wind up keeping some form of this check long term, it would + /// probably be better to remove the snapshot parameter and to + /// refactor the constraint set. + pub fn leak_check( + &mut self, + tcx: TyCtxt<'_, '_, 'tcx>, + overly_polymorphic: bool, + placeholder_map: &PlaceholderMap<'tcx>, + _snapshot: &CombinedSnapshot<'_, 'tcx>, + ) -> RelateResult<'tcx, ()> { + debug!("leak_check(placeholders={:?})", placeholder_map); + + assert!(self.in_snapshot()); + + // If the user gave `-Zno-leak-check`, then skip the leak + // check completely. This is wildly unsound and also not + // unlikely to cause an ICE or two. It is intended for use + // only during a transition period, in which the MIR typeck + // uses the "universe-style" check, and the rest of typeck + // uses the more conservative leak check. Since the leak + // check is more conservative, we can't test the + // universe-style check without disabling it. + if tcx.sess.opts.debugging_opts.no_leak_check { + return Ok(()); + } + + // Go through each placeholder that we created. + for (_, &placeholder_region) in placeholder_map { + // Find the universe this placeholder inhabits. + let placeholder = match placeholder_region { + ty::RePlaceholder(p) => p, + _ => bug!( + "leak_check: expected placeholder found {:?}", + placeholder_region, + ), + }; + + // Find all regions that are related to this placeholder + // in some way. This means any region that either outlives + // or is outlived by a placeholder. + let mut taint_set = TaintSet::new( + TaintDirections::both(), + placeholder_region, + ); + taint_set.fixed_point(tcx, &self.undo_log, &self.data.verifys); + let tainted_regions = taint_set.into_set(); + + // Report an error if two placeholders in the same universe + // are related to one another, or if a placeholder is related + // to something from a parent universe. + for &tainted_region in &tainted_regions { + if let ty::RePlaceholder(_) = tainted_region { + // Two placeholders cannot be related: + if tainted_region == placeholder_region { + continue; + } + } else if self.universe(tainted_region).can_name(placeholder.universe) { + continue; + } + + return Err(if overly_polymorphic { + debug!("Overly polymorphic!"); + TypeError::RegionsOverlyPolymorphic(placeholder.name, tainted_region) + } else { + debug!("Not as polymorphic!"); + TypeError::RegionsInsufficientlyPolymorphic(placeholder.name, tainted_region) + }); + } + } + + Ok(()) + } +} + +#[derive(Debug)] +struct TaintSet<'tcx> { + directions: TaintDirections, + regions: FxHashSet>, +} + +impl<'tcx> TaintSet<'tcx> { + fn new(directions: TaintDirections, initial_region: ty::Region<'tcx>) -> Self { + let mut regions = FxHashSet::default(); + regions.insert(initial_region); + TaintSet { + directions: directions, + regions: regions, + } + } + + fn fixed_point( + &mut self, + tcx: TyCtxt<'_, '_, 'tcx>, + undo_log: &[UndoLog<'tcx>], + verifys: &[Verify<'tcx>], + ) { + let mut prev_len = 0; + while prev_len < self.len() { + debug!( + "tainted: prev_len = {:?} new_len = {:?}", + prev_len, + self.len() + ); + + prev_len = self.len(); + + for undo_entry in undo_log { + match undo_entry { + &AddConstraint(Constraint::VarSubVar(a, b)) => { + self.add_edge(tcx.mk_region(ReVar(a)), tcx.mk_region(ReVar(b))); + } + &AddConstraint(Constraint::RegSubVar(a, b)) => { + self.add_edge(a, tcx.mk_region(ReVar(b))); + } + &AddConstraint(Constraint::VarSubReg(a, b)) => { + self.add_edge(tcx.mk_region(ReVar(a)), b); + } + &AddConstraint(Constraint::RegSubReg(a, b)) => { + self.add_edge(a, b); + } + &AddGiven(a, b) => { + self.add_edge(a, tcx.mk_region(ReVar(b))); + } + &AddVerify(i) => span_bug!( + verifys[i].origin.span(), + "we never add verifications while doing higher-ranked things", + ), + &Purged | &AddCombination(..) | &AddVar(..) => {} + } + } + } + } + + fn into_set(self) -> FxHashSet> { + self.regions + } + + fn len(&self) -> usize { + self.regions.len() + } + + fn add_edge(&mut self, source: ty::Region<'tcx>, target: ty::Region<'tcx>) { + if self.directions.incoming { + if self.regions.contains(&target) { + self.regions.insert(source); + } + } + + if self.directions.outgoing { + if self.regions.contains(&source) { + self.regions.insert(target); + } + } + } +} diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 45d614167ea91..8389f0ab1aa79 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -17,6 +17,8 @@ use crate::ty::{Region, RegionVid}; use std::collections::BTreeMap; use std::{cmp, fmt, mem, u32}; +mod leak_check; + #[derive(Default)] pub struct RegionConstraintCollector<'tcx> { /// For each `RegionVid`, the corresponding `RegionVariableOrigin`. diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs index 8957bbaa4ad7d..60a3777abf844 100644 --- a/src/librustc/traits/auto_trait.rs +++ b/src/librustc/traits/auto_trait.rs @@ -771,7 +771,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { } } &ty::Predicate::RegionOutlives(ref binder) => { - let () = select.infcx().region_outlives_predicate(&dummy_cause, binder); + if select + .infcx() + .region_outlives_predicate(&dummy_cause, binder) + .is_err() + { + return false; + } } &ty::Predicate::TypeOutlives(ref binder) => { match ( diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index eb284645d36c8..3eb49092fed1d 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -730,9 +730,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } ty::Predicate::RegionOutlives(ref predicate) => { - // These errors should show up as region - // inference failures. - panic!("region outlives {:?} failed", predicate); + let predicate = self.resolve_type_vars_if_possible(predicate); + let err = self.region_outlives_predicate(&obligation.cause, + &predicate).err().unwrap(); + struct_span_err!( + self.tcx.sess, span, E0279, + "the requirement `{}` is not satisfied (`{}`)", + predicate, err, + ) } ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => { diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 587f57bb09dee..7648bde1d3c87 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -331,8 +331,10 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, } ty::Predicate::RegionOutlives(ref binder) => { - let () = self.selcx.infcx().region_outlives_predicate(&obligation.cause, binder); - ProcessResult::Changed(vec![]) + match self.selcx.infcx().region_outlives_predicate(&obligation.cause, binder) { + Ok(()) => ProcessResult::Changed(vec![]), + Err(_) => ProcessResult::Error(CodeSelectionError(Unimplemented)), + } } ty::Predicate::TypeOutlives(ref binder) => { diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 5a44d886e3c0a..05141c9daf1d4 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -191,12 +191,15 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>( obligation); let infcx = selcx.infcx(); - infcx.commit_if_ok(|_| { - let (placeholder_predicate, _) = + infcx.commit_if_ok(|snapshot| { + let (placeholder_predicate, placeholder_map) = infcx.replace_bound_vars_with_placeholders(&obligation.predicate); let placeholder_obligation = obligation.with(placeholder_predicate); - project_and_unify_type(selcx, &placeholder_obligation) + let result = project_and_unify_type(selcx, &placeholder_obligation)?; + infcx.leak_check(false, &placeholder_map, snapshot) + .map_err(|err| MismatchedProjectionTypes { err })?; + Ok(result) }) } @@ -1427,9 +1430,8 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>( fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>( selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, - poly_cache_entry: ty::PolyProjectionPredicate<'tcx>) - -> Progress<'tcx> -{ + poly_cache_entry: ty::PolyProjectionPredicate<'tcx>, +) -> Progress<'tcx> { let infcx = selcx.infcx(); let cause = &obligation.cause; let param_env = obligation.param_env; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index c2c05ce7af50b..05fb40ac10a07 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -29,7 +29,7 @@ use super::{ use crate::dep_graph::{DepKind, DepNodeIndex}; use crate::hir::def_id::DefId; -use crate::infer::{InferCtxt, InferOk, TypeFreshener}; +use crate::infer::{CombinedSnapshot, InferCtxt, InferOk, PlaceholderMap, TypeFreshener}; use crate::middle::lang_items; use crate::mir::interpret::GlobalId; use crate::ty::fast_reject; @@ -1667,8 +1667,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { _ => return, } - let result = self.infcx.probe(|_| { - self.match_projection_obligation_against_definition_bounds(obligation) + let result = self.infcx.probe(|snapshot| { + self.match_projection_obligation_against_definition_bounds( + obligation, + snapshot, + ) }); if result { @@ -1679,18 +1682,19 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn match_projection_obligation_against_definition_bounds( &mut self, obligation: &TraitObligation<'tcx>, + snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> bool { let poly_trait_predicate = self.infcx() .resolve_type_vars_if_possible(&obligation.predicate); - let (skol_trait_predicate, _) = self.infcx() + let (placeholder_trait_predicate, placeholder_map) = self.infcx() .replace_bound_vars_with_placeholders(&poly_trait_predicate); debug!( "match_projection_obligation_against_definition_bounds: \ - skol_trait_predicate={:?}", - skol_trait_predicate, + placeholder_trait_predicate={:?}", + placeholder_trait_predicate, ); - let (def_id, substs) = match skol_trait_predicate.trait_ref.self_ty().sty { + let (def_id, substs) = match placeholder_trait_predicate.trait_ref.self_ty().sty { ty::Projection(ref data) => (data.trait_ref(self.tcx()).def_id, data.substs), ty::Opaque(def_id, substs) => (def_id, substs), _ => { @@ -1698,7 +1702,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation.cause.span, "match_projection_obligation_against_definition_bounds() called \ but self-ty is not a projection: {:?}", - skol_trait_predicate.trait_ref.self_ty() + placeholder_trait_predicate.trait_ref.self_ty() ); } }; @@ -1723,7 +1727,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.match_projection( obligation, bound.clone(), - skol_trait_predicate.trait_ref.clone(), + placeholder_trait_predicate.trait_ref.clone(), + &placeholder_map, + snapshot, ) }) }); @@ -1740,7 +1746,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let result = self.match_projection( obligation, bound, - skol_trait_predicate.trait_ref.clone(), + placeholder_trait_predicate.trait_ref.clone(), + &placeholder_map, + snapshot, ); assert!(result); @@ -1753,13 +1761,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, obligation: &TraitObligation<'tcx>, trait_bound: ty::PolyTraitRef<'tcx>, - skol_trait_ref: ty::TraitRef<'tcx>, + placeholder_trait_ref: ty::TraitRef<'tcx>, + placeholder_map: &PlaceholderMap<'tcx>, + snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> bool { - debug_assert!(!skol_trait_ref.has_escaping_bound_vars()); + debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars()); self.infcx .at(&obligation.cause, obligation.param_env) - .sup(ty::Binder::dummy(skol_trait_ref), trait_bound) + .sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound) .is_ok() + && + self.infcx.leak_check(false, placeholder_map, snapshot).is_ok() } /// Given an obligation like ``, search the obligations that the caller @@ -1960,8 +1972,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation.predicate.def_id(), obligation.predicate.skip_binder().trait_ref.self_ty(), |impl_def_id| { - self.infcx.probe(|_| { - if let Ok(_substs) = self.match_impl(impl_def_id, obligation) + self.infcx.probe(|snapshot| { + if let Ok(_substs) = self.match_impl(impl_def_id, obligation, snapshot) { candidates.vec.push(ImplCandidate(impl_def_id)); } @@ -2758,9 +2770,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } fn confirm_projection_candidate(&mut self, obligation: &TraitObligation<'tcx>) { - self.infcx.in_snapshot(|_| { + self.infcx.in_snapshot(|snapshot| { let result = - self.match_projection_obligation_against_definition_bounds(obligation); + self.match_projection_obligation_against_definition_bounds( + obligation, + snapshot, + ); assert!(result); }) } @@ -2912,8 +2927,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // First, create the substitutions by matching the impl again, // this time not in a probe. - self.infcx.in_snapshot(|_| { - let substs = self.rematch_impl(impl_def_id, obligation); + self.infcx.in_snapshot(|snapshot| { + let substs = self.rematch_impl(impl_def_id, obligation, snapshot); debug!("confirm_impl_candidate: substs={:?}", substs); let cause = obligation.derived_cause(ImplDerivedObligation); self.vtable_impl( @@ -3300,9 +3315,27 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { tcx.mk_existential_predicates(iter) }); let source_trait = tcx.mk_dynamic(existential_predicates, r_b); + + // Require that the traits involved in this upcast are **equal**; + // only the **lifetime bound** is changed. + // + // FIXME: This condition is arguably too strong -- it + // would suffice for the source trait to be a + // *subtype* of the target trait. In particular + // changing from something like `for<'a, 'b> Foo<'a, + // 'b>` to `for<'a> Foo<'a, 'a>` should be + // permitted. And, indeed, in the in commit + // 904a0bde93f0348f69914ee90b1f8b6e4e0d7cbc, this + // condition was loosened. However, when the leak check was added + // back, using subtype here actually guies the coercion code in + // such a way that it accepts `old-lub-glb-object.rs`. This is probably + // a good thing, but I've modified this to `.eq` because I want + // to continue rejecting that test (as we have done for quite some time) + // before we are firmly comfortable with what our behavior + // should be there. -nikomatsakis let InferOk { obligations, .. } = self.infcx .at(&obligation.cause, obligation.param_env) - .sup(target, source_trait) + .eq(target, source_trait) // FIXME -- see below .map_err(|_| Unimplemented)?; nested.extend(obligations); @@ -3504,8 +3537,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, impl_def_id: DefId, obligation: &TraitObligation<'tcx>, + snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> Normalized<'tcx, &'tcx Substs<'tcx>> { - match self.match_impl(impl_def_id, obligation) { + match self.match_impl(impl_def_id, obligation, snapshot) { Ok(substs) => substs, Err(()) => { bug!( @@ -3521,6 +3555,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, impl_def_id: DefId, obligation: &TraitObligation<'tcx>, + snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> Result>, ()> { let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); @@ -3531,7 +3566,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return Err(()); } - let (skol_obligation, _) = self.infcx() + let (skol_obligation, placeholder_map) = self.infcx() .replace_bound_vars_with_placeholders(&obligation.predicate); let skol_obligation_trait_ref = skol_obligation.trait_ref; @@ -3563,6 +3598,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?; nested_obligations.extend(obligations); + if let Err(e) = self.infcx.leak_check(false, &placeholder_map, snapshot) { + debug!("match_impl: failed leak check due to `{}`", e); + return Err(()); + } + debug!("match_impl: success impl_substs={:?}", impl_substs); Ok(Normalized { value: impl_substs, diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index e3e0ce147741f..f58e5e4fb69f6 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -1,5 +1,5 @@ use crate::hir::def_id::DefId; -use crate::ty::{self, Region, Ty, TyCtxt}; +use crate::ty::{self, BoundRegion, Region, Ty, TyCtxt}; use std::borrow::Cow; use std::fmt; use rustc_target::spec::abi; @@ -27,6 +27,8 @@ pub enum TypeError<'tcx> { ArgCount, RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>), + RegionsInsufficientlyPolymorphic(BoundRegion, Region<'tcx>), + RegionsOverlyPolymorphic(BoundRegion, Region<'tcx>), RegionsPlaceholderMismatch, Sorts(ExpectedFound>), @@ -101,6 +103,18 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { RegionsDoesNotOutlive(..) => { write!(f, "lifetime mismatch") } + RegionsInsufficientlyPolymorphic(br, _) => { + write!(f, + "expected bound lifetime parameter{}{}, found concrete lifetime", + if br.is_named() { " " } else { "" }, + br) + } + RegionsOverlyPolymorphic(br, _) => { + write!(f, + "expected concrete lifetime, found bound lifetime parameter{}{}", + if br.is_named() { " " } else { "" }, + br) + } RegionsPlaceholderMismatch => { write!(f, "one type is more general than the other") } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index d09cfa84a1690..f9173836cc627 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -434,6 +434,12 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { RegionsDoesNotOutlive(a, b) => { return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b)) } + RegionsInsufficientlyPolymorphic(a, b) => { + return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b)) + } + RegionsOverlyPolymorphic(a, b) => { + return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b)) + } RegionsPlaceholderMismatch => RegionsPlaceholderMismatch, IntMismatch(x) => IntMismatch(x), FloatMismatch(x) => FloatMismatch(x), @@ -1021,6 +1027,8 @@ EnumTypeFoldableImpl! { (ty::error::TypeError::FixedArraySize)(x), (ty::error::TypeError::ArgCount), (ty::error::TypeError::RegionsDoesNotOutlive)(a, b), + (ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b), + (ty::error::TypeError::RegionsOverlyPolymorphic)(a, b), (ty::error::TypeError::RegionsPlaceholderMismatch), (ty::error::TypeError::IntMismatch)(x), (ty::error::TypeError::FloatMismatch)(x), diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.rs b/src/test/ui/anonymous-higher-ranked-lifetime.rs index 55b1667da50b1..2e2a124db9a5d 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.rs +++ b/src/test/ui/anonymous-higher-ranked-lifetime.rs @@ -1,15 +1,26 @@ fn main() { f1(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch f2(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch f3(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch f4(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch f5(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch g1(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch g2(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch g3(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch g4(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch } // Basic diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr index d2c722e32b210..378f352cb9228 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr +++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr @@ -7,13 +7,27 @@ LL | f1(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _` | note: required by `f1` - --> $DIR/anonymous-higher-ranked-lifetime.rs:16:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1 | LL | fn f1(_: F) where F: Fn(&(), &()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:3:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:2:5 + | +LL | f1(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), &()) -> _` + | +note: required by `f1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1 + | +LL | fn f1(_: F) where F: Fn(&(), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5 | LL | f2(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -21,7 +35,7 @@ LL | f2(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _` | note: required by `f2` - --> $DIR/anonymous-higher-ranked-lifetime.rs:17:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1 | LL | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,19 +43,47 @@ LL | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5 | +LL | f2(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&'a (), &()) -> _` + | +note: required by `f2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1 + | +LL | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5 + | LL | f3(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'r> fn(&(), &'r ()) -> _` | note: required by `f3` - --> $DIR/anonymous-higher-ranked-lifetime.rs:18:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1 | LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:5:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5 + | +LL | f3(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), &()) -> _` + | +note: required by `f3` + --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1 + | +LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5 | LL | f4(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -49,13 +91,27 @@ LL | f4(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _` | note: required by `f4` - --> $DIR/anonymous-higher-ranked-lifetime.rs:19:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1 | LL | fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5 + | +LL | f4(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), &'r ()) -> _` + | +note: required by `f4` + --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1 + | +LL | fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5 | LL | f5(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -63,13 +119,27 @@ LL | f5(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r> fn(&'r (), &'r ()) -> _` | note: required by `f5` - --> $DIR/anonymous-higher-ranked-lifetime.rs:20:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:31:1 | LL | fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:7:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5 + | +LL | f5(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&'r (), &'r ()) -> _` + | +note: required by `f5` + --> $DIR/anonymous-higher-ranked-lifetime.rs:31:1 + | +LL | fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 | LL | g1(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -77,13 +147,27 @@ LL | g1(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>) -> _` | note: required by `g1` - --> $DIR/anonymous-higher-ranked-lifetime.rs:23:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1 | LL | fn g1(_: F) where F: Fn(&(), Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 + | +LL | g1(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _` + | +note: required by `g1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1 + | +LL | fn g1(_: F) where F: Fn(&(), Box) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5 | LL | g2(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -91,13 +175,27 @@ LL | g2(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _` | note: required by `g2` - --> $DIR/anonymous-higher-ranked-lifetime.rs:24:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1 | LL | fn g2(_: F) where F: Fn(&(), fn(&())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:9:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5 + | +LL | g2(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), for<'r> fn(&'r ())) -> _` + | +note: required by `g2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1 + | +LL | fn g2(_: F) where F: Fn(&(), fn(&())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5 | LL | g3(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -105,13 +203,27 @@ LL | g3(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'s> fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _` | note: required by `g3` - --> $DIR/anonymous-higher-ranked-lifetime.rs:25:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1 | LL | fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5 + | +LL | g3(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _` + | +note: required by `g3` + --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1 + | +LL | fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5 | LL | g4(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -119,13 +231,27 @@ LL | g4(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _` | note: required by `g4` - --> $DIR/anonymous-higher-ranked-lifetime.rs:26:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:37:1 + | +LL | fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5 + | +LL | g4(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), for<'r> fn(&'r ())) -> _` + | +note: required by `g4` + --> $DIR/anonymous-higher-ranked-lifetime.rs:37:1 | LL | fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:11:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5 | LL | h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch | ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _` @@ -133,13 +259,27 @@ LL | h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<(dyn for<'t0> std::ops::Fn(&'t0 ()) + 'static)>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _` | note: required by `h1` - --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1 | LL | fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5 + | +LL | h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch + | ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _` + | | + | expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &(), for<'r, 's> fn(&'r (), &'s ())) -> _` + | +note: required by `h1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1 + | +LL | fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5 | LL | h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch | ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _` @@ -147,11 +287,25 @@ LL | h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _` | note: required by `h2` - --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:41:1 + | +LL | fn h2(_: F) where F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5 + | +LL | h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch + | ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _` + | | + | expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &'t0 (), for<'r, 's> fn(&'r (), &'s ())) -> _` + | +note: required by `h2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:41:1 | LL | fn h2(_: F) where F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 22 previous errors For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/associated-types/associated-types-eq-hr.rs b/src/test/ui/associated-types/associated-types-eq-hr.rs index 20fa1e7a48db1..e6afa3f71c2f0 100644 --- a/src/test/ui/associated-types/associated-types-eq-hr.rs +++ b/src/test/ui/associated-types/associated-types-eq-hr.rs @@ -89,12 +89,14 @@ pub fn call_bar() { pub fn call_tuple_one() { tuple_one::(); - //~^ ERROR not general enough + //~^ ERROR not satisfied + //~| ERROR type mismatch } pub fn call_tuple_two() { tuple_two::(); - //~^ ERROR not general enough + //~^ ERROR not satisfied + //~| ERROR type mismatch } pub fn call_tuple_three() { @@ -103,7 +105,7 @@ pub fn call_tuple_three() { pub fn call_tuple_four() { tuple_four::(); - //~^ ERROR not general enough + //~^ ERROR not satisfied } fn main() { } diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr index 5299ebbb1ba8a..3721b69898876 100644 --- a/src/test/ui/associated-types/associated-types-eq-hr.stderr +++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr @@ -34,36 +34,93 @@ LL | | // ok for UintStruct, but not IntStruct LL | | } | |_^ -error: implementation of `TheTrait` is not general enough +error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied --> $DIR/associated-types-eq-hr.rs:91:5 | LL | tuple_one::(); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple` | - = note: Due to a where-clause on `tuple_one`, - = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` + = help: the following implementations were found: + > +note: required by `tuple_one` + --> $DIR/associated-types-eq-hr.rs:56:1 + | +LL | / fn tuple_one() +LL | | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize> +LL | | { +LL | | // not ok for tuple, two lifetimes and we pick first +LL | | } + | |_^ -error: implementation of `TheTrait` is not general enough - --> $DIR/associated-types-eq-hr.rs:96:5 +error[E0271]: type mismatch resolving `for<'x, 'y> >::A == &'x isize` + --> $DIR/associated-types-eq-hr.rs:91:5 + | +LL | tuple_one::(); + | ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime + | +note: required by `tuple_one` + --> $DIR/associated-types-eq-hr.rs:56:1 + | +LL | / fn tuple_one() +LL | | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize> +LL | | { +LL | | // not ok for tuple, two lifetimes and we pick first +LL | | } + | |_^ + +error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied + --> $DIR/associated-types-eq-hr.rs:97:5 | LL | tuple_two::(); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple` + | + = help: the following implementations were found: + > +note: required by `tuple_two` + --> $DIR/associated-types-eq-hr.rs:62:1 | - = note: Due to a where-clause on `tuple_two`, - = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` +LL | / fn tuple_two() +LL | | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize> +LL | | { +LL | | // not ok for tuple, two lifetimes and we pick second +LL | | } + | |_^ + +error[E0271]: type mismatch resolving `for<'x, 'y> >::A == &'y isize` + --> $DIR/associated-types-eq-hr.rs:97:5 + | +LL | tuple_two::(); + | ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime + | +note: required by `tuple_two` + --> $DIR/associated-types-eq-hr.rs:62:1 + | +LL | / fn tuple_two() +LL | | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize> +LL | | { +LL | | // not ok for tuple, two lifetimes and we pick second +LL | | } + | |_^ -error: implementation of `TheTrait` is not general enough - --> $DIR/associated-types-eq-hr.rs:105:5 +error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied + --> $DIR/associated-types-eq-hr.rs:107:5 | LL | tuple_four::(); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple` + | + = help: the following implementations were found: + > +note: required by `tuple_four` + --> $DIR/associated-types-eq-hr.rs:74:1 | - = note: Due to a where-clause on `tuple_four`, - = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` +LL | / fn tuple_four() +LL | | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)> +LL | | { +LL | | // not ok for tuple, two lifetimes, and lifetime matching is invariant +LL | | } + | |_^ -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0271`. +Some errors occurred: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr index 811c9a8f5e12b..cc69e849fe144 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr @@ -1,12 +1,17 @@ -error[E0308]: mismatched types +error[E0271]: type mismatch resolving `for<'a> <&'a _ as Mirror>::Image == _` --> $DIR/higher-ranked-projection.rs:25:5 | LL | foo(()); - | ^^^ one type is more general than the other + | ^^^ expected bound lifetime parameter 'a, found concrete lifetime | - = note: expected type `&'a ()` - found type `&()` +note: required by `foo` + --> $DIR/higher-ranked-projection.rs:14:1 + | +LL | / fn foo(_t: T) +LL | | where for<'a> &'a T: Mirror +LL | | {} + | |__^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/associated-types/higher-ranked-projection.good.stderr b/src/test/ui/associated-types/higher-ranked-projection.good.stderr index 92fd256285852..165e5213e0d34 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.good.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.good.stderr @@ -3,7 +3,7 @@ error: compilation successful | LL | / fn main() { //[good]~ ERROR compilation successful LL | | foo(()); -LL | | //[bad]~^ ERROR mismatched types +LL | | //[bad]~^ ERROR type mismatch LL | | } | |_^ diff --git a/src/test/ui/associated-types/higher-ranked-projection.rs b/src/test/ui/associated-types/higher-ranked-projection.rs index fd7252f9e2253..a2ea6d8f206b6 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.rs +++ b/src/test/ui/associated-types/higher-ranked-projection.rs @@ -23,5 +23,5 @@ fn foo(_t: T) #[rustc_error] fn main() { //[good]~ ERROR compilation successful foo(()); - //[bad]~^ ERROR mismatched types + //[bad]~^ ERROR type mismatch } diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs b/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs index 6977fd47a2e85..a4e43da91baf8 100644 --- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs +++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs @@ -28,14 +28,14 @@ fn expect_free_supply_bound() { // Here, we are given a function whose region is bound at closure level, // but we expect one bound in the argument. Error results. with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {}); - //~^ ERROR mismatched types + //~^ ERROR type mismatch } fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) { // Here, we are given a `fn(&u32)` but we expect a `fn(&'x // u32)`. In principle, this could be ok, but we demand equality. with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {}); - //~^ ERROR mismatched types + //~^ ERROR type mismatch } fn expect_bound_supply_free_from_closure() { @@ -44,7 +44,7 @@ fn expect_bound_supply_free_from_closure() { // the argument level. type Foo<'a> = fn(&'a u32); with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| { - //~^ ERROR mismatched types + //~^ ERROR type mismatch }); } diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr index b1cfd6cef1022..ab35aeff697b7 100644 --- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr +++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr @@ -36,33 +36,58 @@ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the b LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {}); | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/expect-fn-supply-fn.rs:30:52 +error[E0631]: type mismatch in closure arguments + --> $DIR/expect-fn-supply-fn.rs:30:5 | LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {}); - | ^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _` + | | + | expected signature of `fn(fn(&'a u32), &i32) -> _` | - = note: expected type `fn(&u32)` - found type `for<'r> fn(&'r u32)` +note: required by `with_closure_expecting_fn_with_free_region` + --> $DIR/expect-fn-supply-fn.rs:1:1 + | +LL | / fn with_closure_expecting_fn_with_free_region(_: F) +LL | | where F: for<'a> FnOnce(fn(&'a u32), &i32) +LL | | { +LL | | } + | |_^ -error[E0308]: mismatched types - --> $DIR/expect-fn-supply-fn.rs:37:53 +error[E0631]: type mismatch in closure arguments + --> $DIR/expect-fn-supply-fn.rs:37:5 | LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {}); - | ^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _` + | | + | expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _` | - = note: expected type `for<'r> fn(&'r u32)` - found type `fn(&'x u32)` +note: required by `with_closure_expecting_fn_with_bound_region` + --> $DIR/expect-fn-supply-fn.rs:6:1 + | +LL | / fn with_closure_expecting_fn_with_bound_region(_: F) +LL | | where F: FnOnce(fn(&u32), &i32) +LL | | { +LL | | } + | |_^ -error[E0308]: mismatched types - --> $DIR/expect-fn-supply-fn.rs:46:53 +error[E0631]: type mismatch in closure arguments + --> $DIR/expect-fn-supply-fn.rs:46:5 | LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| { - | ^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _` + | | + | expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _` + | +note: required by `with_closure_expecting_fn_with_bound_region` + --> $DIR/expect-fn-supply-fn.rs:6:1 | - = note: expected type `for<'r> fn(&'r u32)` - found type `fn(&u32)` +LL | / fn with_closure_expecting_fn_with_bound_region(_: F) +LL | | where F: FnOnce(fn(&u32), &i32) +LL | | { +LL | | } + | |_^ error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors occurred: E0308, E0631. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/coherence/coherence-subtyping.old.stderr b/src/test/ui/coherence/coherence-subtyping.old.stderr deleted file mode 100644 index db9f9f7665374..0000000000000 --- a/src/test/ui/coherence/coherence-subtyping.old.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0119]: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: - --> $DIR/coherence-subtyping.rs:15:1 - | -LL | impl TheTrait for for<'a,'b> fn(&'a u8, &'b u8) -> &'a u8 { - | --------------------------------------------------------- first implementation here -... -LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` - | - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-subtyping.re.stderr b/src/test/ui/coherence/coherence-subtyping.re.stderr deleted file mode 100644 index db9f9f7665374..0000000000000 --- a/src/test/ui/coherence/coherence-subtyping.re.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0119]: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: - --> $DIR/coherence-subtyping.rs:15:1 - | -LL | impl TheTrait for for<'a,'b> fn(&'a u8, &'b u8) -> &'a u8 { - | --------------------------------------------------------- first implementation here -... -LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` - | - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs index f27e14eab63da..e74067578069e 100644 --- a/src/test/ui/coherence/coherence-subtyping.rs +++ b/src/test/ui/coherence/coherence-subtyping.rs @@ -1,7 +1,11 @@ // Test that two distinct impls which match subtypes of one another // yield coherence errors (or not) depending on the variance. +// +// Note: This scenario is currently accepted, but as part of the +// universe transition (#56105) may eventually become an error. // revisions: old re +// compile-pass #![cfg_attr(re, feature(re_rebalance_coherence))] @@ -13,8 +17,6 @@ impl TheTrait for for<'a,'b> fn(&'a u8, &'b u8) -> &'a u8 { } impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - //[old]~^ ERROR - //[re]~^^ ERROR } fn main() { } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr index bdfabdabbebb7..8e2b0b8c60045 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/hr-subtype.rs:39:26 | LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a ... LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32, LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr index 25b74d855bb48..dbb5018139076 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr @@ -1,14 +1,16 @@ -error: compilation successful - --> $DIR/hr-subtype.rs:96:1 +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:39:26 | -LL | / fn main() { -LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful -LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful -LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful -LL | | } - | |_^ +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a +... +LL | / check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32), +LL | | for<'a> fn(&'a u32, &'a u32)) } + | |__________________________________________________________________- in this macro invocation + | + = note: expected type `std::option::Option fn(&'a u32, &'b u32)>` + found type `std::option::Option fn(&'a u32, &'a u32)>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr index 25b74d855bb48..5fcb63e17bf31 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr @@ -1,12 +1,12 @@ error: compilation successful - --> $DIR/hr-subtype.rs:96:1 + --> $DIR/hr-subtype.rs:100:1 | LL | / fn main() { LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful +LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful +LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful LL | | } | |_^ diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr index 25b74d855bb48..5fcb63e17bf31 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr @@ -1,12 +1,12 @@ error: compilation successful - --> $DIR/hr-subtype.rs:96:1 + --> $DIR/hr-subtype.rs:100:1 | LL | / fn main() { LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful +LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful +LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful LL | | } | |_^ diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr index 74b8c89b6e86f..db9892b48a6f7 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/hr-subtype.rs:39:26 | LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a ... LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), LL | | fn(&'x u32)) } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr index 25b74d855bb48..e9fb73411bd39 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr @@ -1,14 +1,16 @@ -error: compilation successful - --> $DIR/hr-subtype.rs:96:1 +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:39:26 | -LL | / fn main() { -LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful -LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful -LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful -LL | | } - | |_^ +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a +... +LL | / check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>), +LL | | for<'a> fn(Co<'a>, Co<'a>)) } + | |______________________________________________________________________- in this macro invocation + | + = note: expected type `std::option::Option fn(Co<'a>, Co<'b>)>` + found type `std::option::Option fn(Co<'a>, Co<'a>)>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr index 25b74d855bb48..d0e80faa68e8b 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr @@ -1,14 +1,16 @@ -error: compilation successful - --> $DIR/hr-subtype.rs:96:1 +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:39:26 | -LL | / fn main() { -LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful -LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful -LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful -LL | | } - | |_^ +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a +... +LL | / check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>, +LL | | for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) } + | |______________________________________________________________________________________- in this macro invocation + | + = note: expected type `std::option::Option fn(Co<'a>, Co<'b>) -> Contra<'a>>` + found type `std::option::Option fn(Co<'a>, Co<'a>) -> Contra<'a>>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr index 25b74d855bb48..5fcb63e17bf31 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr @@ -1,12 +1,12 @@ error: compilation successful - --> $DIR/hr-subtype.rs:96:1 + --> $DIR/hr-subtype.rs:100:1 | LL | / fn main() { LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful +LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful +LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful LL | | } | |_^ diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr index 25b74d855bb48..3605ecf4f8667 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr @@ -1,14 +1,16 @@ -error: compilation successful - --> $DIR/hr-subtype.rs:96:1 +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:39:26 | -LL | / fn main() { -LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful -LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful -LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful -LL | | } - | |_^ +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a +... +LL | / check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>, +LL | | for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) } + | |______________________________________________________________________________________________- in this macro invocation + | + = note: expected type `std::option::Option fn(Contra<'a>, Contra<'b>) -> Co<'a>>` + found type `std::option::Option fn(Contra<'a>, Contra<'a>) -> Co<'a>>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr index 8168941e2777c..fae6e9b5c89ca 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/hr-subtype.rs:39:26 | LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a ... LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), LL | | for<'a> fn(Inv<'a>, Inv<'a>)) } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr index 25b74d855bb48..5fcb63e17bf31 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr @@ -1,12 +1,12 @@ error: compilation successful - --> $DIR/hr-subtype.rs:96:1 + --> $DIR/hr-subtype.rs:100:1 | LL | / fn main() { LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful +LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful +LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful LL | | } | |_^ diff --git a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr index 25b74d855bb48..5fcb63e17bf31 100644 --- a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr @@ -1,12 +1,12 @@ error: compilation successful - --> $DIR/hr-subtype.rs:96:1 + --> $DIR/hr-subtype.rs:100:1 | LL | / fn main() { LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful +LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful +LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful LL | | } | |_^ diff --git a/src/test/ui/hr-subtype/hr-subtype.rs b/src/test/ui/hr-subtype/hr-subtype.rs index ad4f39f840528..2f7c1e6fd8c0d 100644 --- a/src/test/ui/hr-subtype/hr-subtype.rs +++ b/src/test/ui/hr-subtype/hr-subtype.rs @@ -42,6 +42,10 @@ macro_rules! check { //[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR //[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^ ERROR //[free_inv_x_vs_free_inv_y]~^^^^^ ERROR + //[bound_a_b_vs_bound_a]~^^^^^^ ERROR mismatched types + //[bound_co_a_co_b_ret_contra_a]~^^^^^^^ ERROR + //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^ ERROR + //[bound_co_a_b_vs_bound_co_a]~^^^^^^^^^ ERROR } } } @@ -99,8 +103,4 @@ fn main() { //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful //[free_x_vs_free_x]~^^^^^ ERROR compilation successful -//[bound_a_b_vs_bound_a]~^^^^^^ ERROR compilation successful -//[bound_co_a_co_b_ret_contra_a]~^^^^^^^ ERROR compilation successful -//[bound_co_a_b_vs_bound_co_a]~^^^^^^^^ ERROR compilation successful -//[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful } diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr index 630dda2694fde..50e1af8f14231 100644 --- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr +++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr @@ -1,12 +1,20 @@ -error: implementation of `Foo` is not general enough +error[E0277]: the trait bound `for<'a, 'b> SomeStruct: Foo<(&'a isize, &'b isize)>` is not satisfied --> $DIR/hrtb-conflate-regions.rs:28:10 | LL | fn b() { want_foo2::(); } //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct` | - = note: Due to a where-clause on `want_foo2`, - = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `SomeStruct` actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` + = help: the following implementations were found: + > +note: required by `want_foo2` + --> $DIR/hrtb-conflate-regions.rs:8:1 + | +LL | / fn want_foo2() +LL | | where T : for<'a,'b> Foo<(&'a isize, &'b isize)> +LL | | { +LL | | } + | |_^ error: aborting due to previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr b/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr index 6301ed45ac277..8e8892552b701 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/hrtb-exists-forall-fn.rs:17:34 | LL | let _: for<'b> fn(&'b u32) = foo(); //~ ERROR mismatched types - | ^^^^^ one type is more general than the other + | ^^^^^ expected concrete lifetime, found bound lifetime parameter 'b | = note: expected type `for<'b> fn(&'b u32)` found type `fn(&u32)` diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs index 8801760056ecb..4c1d4d28a09b0 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs @@ -1,9 +1,7 @@ -// Test a `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile! +// Test a case where variance and higher-ranked types interact in surprising ways. // // In particular, we test this pattern in trait solving, where it is not connected // to any part of the source code. -// -// compile-pass trait Trait {} @@ -30,6 +28,9 @@ fn main() { // - `?a: ?b` -- solveable if `?b` is also inferred to `'empty` // - So the subtyping check succeeds, somewhat surprisingly. // This is because we can use `'empty`. + // + // NB. *However*, the reinstated leak-check gives an error here. foo::<()>(); + //~^ ERROR not satisfied } diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr new file mode 100644 index 0000000000000..7f2ca037f0f49 --- /dev/null +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `(): Trait fn(&'b u32)>` is not satisfied + --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5 + | +LL | foo::<()>(); + | ^^^^^^^^^ the trait `Trait fn(&'b u32)>` is not implemented for `()` + | + = help: the following implementations were found: + <() as Trait> +note: required by `foo` + --> $DIR/hrtb-exists-forall-trait-contravariant.rs:8:1 + | +LL | / fn foo() +LL | | where +LL | | T: Trait fn(&'b u32)>, +LL | | { +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs index da1bb7cd5fd0b..95b57d6c5bb5e 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs @@ -1,9 +1,7 @@ -// Test a `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile! +// Test a case where variance and higher-ranked types interact in surprising ways. // // In particular, we test this pattern in trait solving, where it is not connected // to any part of the source code. -// -// compile-pass trait Trait {} @@ -32,6 +30,9 @@ fn main() { // - `?b: ?a` -- solveable if `?b` is inferred to `'static` // - So the subtyping check succeeds, somewhat surprisingly. // This is because we can use `'static`. + // + // NB. *However*, the reinstated leak-check gives an error here. foo::<()>(); + //~^ ERROR not satisfied } diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr new file mode 100644 index 0000000000000..cd5982e7588a7 --- /dev/null +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `(): Trait fn(fn(&'b u32))>` is not satisfied + --> $DIR/hrtb-exists-forall-trait-covariant.rs:36:5 + | +LL | foo::<()>(); + | ^^^^^^^^^ the trait `Trait fn(fn(&'b u32))>` is not implemented for `()` + | + = help: the following implementations were found: + <() as Trait> +note: required by `foo` + --> $DIR/hrtb-exists-forall-trait-covariant.rs:8:1 + | +LL | / fn foo() +LL | | where +LL | | T: Trait fn(fn(&'b u32))>, +LL | | { +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs index da3f8ad1b8957..827a68beee8bd 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs @@ -25,5 +25,5 @@ fn main() { // yielding `fn(&!b u32)`, in a fresh universe U1 // - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`. - foo::<()>(); //~ ERROR not general enough + foo::<()>(); //~ ERROR not satisfied } diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr index a44837a1e26fd..f56b81759fede 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr @@ -1,12 +1,21 @@ -error: implementation of `Trait` is not general enough +error[E0277]: the trait bound `(): Trait fn(std::cell::Cell<&'b u32>)>` is not satisfied --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5 | -LL | foo::<()>(); //~ ERROR not general enough - | ^^^^^^^^^ +LL | foo::<()>(); //~ ERROR not satisfied + | ^^^^^^^^^ the trait `Trait fn(std::cell::Cell<&'b u32>)>` is not implemented for `()` | - = note: Due to a where-clause on `foo`, - = note: `()` must implement `Trait fn(std::cell::Cell<&'b u32>)>` - = note: but `()` actually implements `Trait)>`, for some specific lifetime `'0` + = help: the following implementations were found: + <() as Trait)>> +note: required by `foo` + --> $DIR/hrtb-exists-forall-trait-invariant.rs:10:1 + | +LL | / fn foo() +LL | | where +LL | | T: Trait fn(Cell<&'b u32>)>, +LL | | { +LL | | } + | |_^ error: aborting due to previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr index 0d7b5cbf82348..77c1789852e52 100644 --- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr +++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr @@ -1,12 +1,19 @@ -error[E0308]: mismatched types +error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5 | LL | want_bar_for_any_ccx(b); //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` | - = note: expected type `for<'ccx> Bar<'ccx>` - found type `Bar<'static>` + = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound +note: required by `want_bar_for_any_ccx` + --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:31:1 + | +LL | / fn want_bar_for_any_ccx(b: &B) +LL | | where B : for<'ccx> Bar<'ccx> +LL | | { +LL | | } + | |_^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs index 3d2d403462d8b..48ebe5017aa62 100644 --- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs +++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs @@ -15,7 +15,7 @@ fn want_foo_for_some_tcx<'x,F>(f: &'x F) where F : Foo<'x> { want_foo_for_some_tcx(f); - want_foo_for_any_tcx(f); //~ ERROR E0308 + want_foo_for_any_tcx(f); //~ ERROR not satisfied } fn want_foo_for_any_tcx(f: &F) @@ -32,7 +32,7 @@ fn want_bar_for_some_ccx<'x,B>(b: &B) want_foo_for_any_tcx(b); want_bar_for_some_ccx(b); - want_bar_for_any_ccx(b); //~ ERROR E0308 + want_bar_for_any_ccx(b); //~ ERROR not satisfied } fn want_bar_for_any_ccx(b: &B) diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr index 31dbeec2a551b..5914cb3eaa494 100644 --- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr +++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr @@ -1,21 +1,40 @@ -error[E0308]: mismatched types +error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied --> $DIR/hrtb-higher-ranker-supertraits.rs:18:5 | -LL | want_foo_for_any_tcx(f); //~ ERROR E0308 - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +LL | want_foo_for_any_tcx(f); //~ ERROR not satisfied + | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F` | - = note: expected type `for<'tcx> Foo<'tcx>` - found type `Foo<'x>` + = help: consider adding a `where for<'tcx> F: Foo<'tcx>` bound +note: required by `want_foo_for_any_tcx` + --> $DIR/hrtb-higher-ranker-supertraits.rs:21:1 + | +LL | / fn want_foo_for_any_tcx(f: &F) +LL | | where F : for<'tcx> Foo<'tcx> +LL | | { +LL | | want_foo_for_some_tcx(f); +LL | | want_foo_for_any_tcx(f); +LL | | } + | |_^ -error[E0308]: mismatched types +error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied --> $DIR/hrtb-higher-ranker-supertraits.rs:35:5 | -LL | want_bar_for_any_ccx(b); //~ ERROR E0308 - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +LL | want_bar_for_any_ccx(b); //~ ERROR not satisfied + | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` + | + = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound +note: required by `want_bar_for_any_ccx` + --> $DIR/hrtb-higher-ranker-supertraits.rs:38:1 | - = note: expected type `for<'ccx> Bar<'ccx>` - found type `Bar<'x>` +LL | / fn want_bar_for_any_ccx(b: &B) +LL | | where B : for<'ccx> Bar<'ccx> +LL | | { +LL | | want_foo_for_some_tcx(b); +... | +LL | | want_bar_for_any_ccx(b); +LL | | } + | |_^ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr index 99c87f13672b1..fe2bc1f222504 100644 --- a/src/test/ui/hrtb/hrtb-just-for-static.stderr +++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr @@ -1,22 +1,37 @@ -error: implementation of `Foo` is not general enough +error[E0277]: the trait bound `for<'a> StaticInt: Foo<&'a isize>` is not satisfied --> $DIR/hrtb-just-for-static.rs:24:5 | LL | want_hrtb::() //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt` | - = note: Due to a where-clause on `want_hrtb`, - = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0` - = note: but `StaticInt` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1` + = help: the following implementations were found: + > +note: required by `want_hrtb` + --> $DIR/hrtb-just-for-static.rs:8:1 + | +LL | / fn want_hrtb() +LL | | where T : for<'a> Foo<&'a isize> +LL | | { +LL | | } + | |_^ -error: implementation of `Foo` is not general enough +error[E0277]: the trait bound `for<'a> &'a u32: Foo<&'a isize>` is not satisfied --> $DIR/hrtb-just-for-static.rs:30:5 | LL | want_hrtb::<&'a u32>() //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `&'a u32` + | + = help: the following implementations were found: + <&'a u32 as Foo<&'a isize>> +note: required by `want_hrtb` + --> $DIR/hrtb-just-for-static.rs:8:1 | - = note: Due to a where-clause on `want_hrtb`, - = note: `Foo<&'0 isize>` would have to be implemented for the type `&'a u32`, for any lifetime `'0` - = note: but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` +LL | / fn want_hrtb() +LL | | where T : for<'a> Foo<&'a isize> +LL | | { +LL | | } + | |_^ error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/issue-46989.rs b/src/test/ui/hrtb/issue-46989.rs new file mode 100644 index 0000000000000..2c85905545807 --- /dev/null +++ b/src/test/ui/hrtb/issue-46989.rs @@ -0,0 +1,42 @@ +// Regression test for #46989: +// +// In the move to universes, this test started passing. +// It is not necessarily WRONG to do so, but it was a bit +// surprising. The reason that it passed is that when we were +// asked to prove that +// +// for<'a> fn(&'a i32): Foo +// +// we were able to use the impl below to prove +// +// fn(&'empty i32): Foo +// +// and then we were able to prove that +// +// fn(&'empty i32) = for<'a> fn(&'a i32) +// +// This last fact is somewhat surprising, but essentially "falls out" +// from handling variance correctly. In particular, consider the subtyping +// relations. First: +// +// fn(&'empty i32) <: for<'a> fn(&'a i32) +// +// This holds because -- intuitively -- a fn that takes a reference but doesn't use +// it can be given a reference with any lifetime. Similarly, the opposite direction: +// +// for<'a> fn(&'a i32) <: fn(&'empty i32) +// +// holds because 'a can be instantiated to 'empty. + +trait Foo { + +} + +impl Foo for fn(A) { } + +fn assert_foo() {} + +fn main() { + assert_foo::(); + //~^ ERROR the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied +} diff --git a/src/test/ui/hrtb/issue-46989.stderr b/src/test/ui/hrtb/issue-46989.stderr new file mode 100644 index 0000000000000..b308291d5c0eb --- /dev/null +++ b/src/test/ui/hrtb/issue-46989.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied + --> $DIR/issue-46989.rs:40:5 + | +LL | assert_foo::(); + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `for<'r> fn(&'r i32)` + | + = help: the following implementations were found: + +note: required by `assert_foo` + --> $DIR/issue-46989.rs:37:1 + | +LL | fn assert_foo() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/issue-57639.rs b/src/test/ui/hrtb/issue-57639.rs new file mode 100644 index 0000000000000..4bcaef3616bd5 --- /dev/null +++ b/src/test/ui/hrtb/issue-57639.rs @@ -0,0 +1,29 @@ +// Regression test for #57639: +// +// In the move to universes, this test stopped working. The problem +// was that when the trait solver was asked to prove `for<'a> T::Item: +// Foo<'a>` as part of WF checking, it wound up "eagerly committing" +// to the where clause, which says that `T::Item: Foo<'a>`, but it +// should instead have been using the bound found in the trait +// declaration. Pre-universe, this used to work out ok because we got +// "eager errors" due to the leak check. +// +// See [this comment on GitHub][c] for more details. +// +// run-pass +// +// [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861 + +trait Foo<'a> {} + +trait Bar { + type Item: for<'a> Foo<'a>; +} + +fn foo<'a, T>(_: T) +where + T: Bar, + T::Item: Foo<'a>, +{} + +fn main() { } diff --git a/src/test/ui/hrtb/issue-58451.rs b/src/test/ui/hrtb/issue-58451.rs new file mode 100644 index 0000000000000..229e505767879 --- /dev/null +++ b/src/test/ui/hrtb/issue-58451.rs @@ -0,0 +1,13 @@ +// Regression test for #58451: +// +// Error reporting here encountered an ICE in the shift to universes. + +fn f(i: I) +where + I: IntoIterator, + I::Item: for<'a> Into<&'a ()>, +{} + +fn main() { + f(&[f()]); //~ ERROR this function takes 1 parameter +} diff --git a/src/test/ui/hrtb/issue-58451.stderr b/src/test/ui/hrtb/issue-58451.stderr new file mode 100644 index 0000000000000..79c24855dc96c --- /dev/null +++ b/src/test/ui/hrtb/issue-58451.stderr @@ -0,0 +1,16 @@ +error[E0061]: this function takes 1 parameter but 0 parameters were supplied + --> $DIR/issue-58451.rs:12:9 + | +LL | / fn f(i: I) +LL | | where +LL | | I: IntoIterator, +LL | | I::Item: for<'a> Into<&'a ()>, +LL | | {} + | |__- defined here +... +LL | f(&[f()]); //~ ERROR this function takes 1 parameter + | ^^^ expected 1 parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/issues/issue-40000.stderr b/src/test/ui/issues/issue-40000.stderr index d7966cea52bb0..ce0c44c147563 100644 --- a/src/test/ui/issues/issue-40000.stderr +++ b/src/test/ui/issues/issue-40000.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/issue-40000.rs:6:9 | LL | foo(bar); //~ ERROR E0308 - | ^^^ one type is more general than the other + | ^^^ expected concrete lifetime, found bound lifetime parameter | - = note: expected type `dyn for<'r> std::ops::Fn(&'r i32)` - found type `dyn std::ops::Fn(&i32)` + = note: expected type `std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r i32) + 'static)>` + found type `std::boxed::Box` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57362-1.rs b/src/test/ui/issues/issue-57362-1.rs index fe6b69f00977d..1fa417fe98ab7 100644 --- a/src/test/ui/issues/issue-57362-1.rs +++ b/src/test/ui/issues/issue-57362-1.rs @@ -17,7 +17,7 @@ impl Trait for fn(&T) { fn f() { let a: fn(_) = |_: &u8| {}; - a.f(); //~ ERROR not general enough + a.f(); //~ ERROR no method named `f` } fn main() {} diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr index 06946bcf744a7..b21b35849b172 100644 --- a/src/test/ui/issues/issue-57362-1.stderr +++ b/src/test/ui/issues/issue-57362-1.stderr @@ -1,11 +1,14 @@ -error: implementation of `Trait` is not general enough +error[E0599]: no method named `f` found for type `fn(&u8)` in the current scope --> $DIR/issue-57362-1.rs:20:7 | -LL | a.f(); //~ ERROR not general enough +LL | a.f(); //~ ERROR no method named `f` | ^ | - = note: `Trait` would have to be implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0` - = note: but `Trait` is actually implemented for the type `for<'r> fn(&'r u8)` + = note: a is a function, perhaps you wish to call it + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `f`, perhaps you need to implement it: + candidate #1: `Trait` error: aborting due to previous error +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-57362-2.rs b/src/test/ui/issues/issue-57362-2.rs index 436a4a904576d..870d7f28ba953 100644 --- a/src/test/ui/issues/issue-57362-2.rs +++ b/src/test/ui/issues/issue-57362-2.rs @@ -19,7 +19,7 @@ impl<'a> X for fn(&'a ()) { } fn g() { - let x = ::make_g(); //~ ERROR not general enough + let x = ::make_g(); //~ ERROR no function or associated item } fn main() {} diff --git a/src/test/ui/issues/issue-57362-2.stderr b/src/test/ui/issues/issue-57362-2.stderr index 14b7f52bb8799..b8211691f7be6 100644 --- a/src/test/ui/issues/issue-57362-2.stderr +++ b/src/test/ui/issues/issue-57362-2.stderr @@ -1,11 +1,15 @@ -error: implementation of `X` is not general enough - --> $DIR/issue-57362-2.rs:22:13 +error[E0599]: no function or associated item named `make_g` found for type `for<'r> fn(&'r ())` in the current scope + --> $DIR/issue-57362-2.rs:22:25 | -LL | let x = ::make_g(); //~ ERROR not general enough - | ^^^^^^^^^^^^^^^^^^ +LL | let x = ::make_g(); //~ ERROR no function or associated item + | ------------^^^^^^ + | | + | function or associated item not found in `for<'r> fn(&'r ())` | - = note: `X` would have to be implemented for the type `for<'r> fn(&'r ())` - = note: but `X` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0` + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `make_g`, perhaps you need to implement it: + candidate #1: `X` error: aborting due to previous error +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.rs b/src/test/ui/lub-glb/old-lub-glb-hr.rs index 324dc86bd92b8..6bf1fd41d77be 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr.rs +++ b/src/test/ui/lub-glb/old-lub-glb-hr.rs @@ -4,7 +4,8 @@ // longer get an error, because we recognize these two types as // equivalent! // -// compile-pass +// Whoops -- now that we reinstituted the leak-check, we get an error +// again. fn foo( x: fn(&u8, &u8), @@ -12,7 +13,7 @@ fn foo( ) { let z = match 22 { 0 => x, - _ => y, + _ => y, //~ ERROR match arms have incompatible types }; } diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.stderr b/src/test/ui/lub-glb/old-lub-glb-hr.stderr new file mode 100644 index 0000000000000..8f228ea4cad41 --- /dev/null +++ b/src/test/ui/lub-glb/old-lub-glb-hr.stderr @@ -0,0 +1,18 @@ +error[E0308]: match arms have incompatible types + --> $DIR/old-lub-glb-hr.rs:16:14 + | +LL | let z = match 22 { + | _____________- +LL | | 0 => x, + | | - this is found to be of type `for<'r, 's> fn(&'r u8, &'s u8)` +LL | | _ => y, //~ ERROR match arms have incompatible types + | | ^ expected bound lifetime parameter, found concrete lifetime +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected type `for<'r, 's> fn(&'r u8, &'s u8)` + found type `for<'a> fn(&'a u8, &'a u8)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lub-glb/old-lub-glb-object.rs b/src/test/ui/lub-glb/old-lub-glb-object.rs index 9be7a813603d4..dcd604a5157e2 100644 --- a/src/test/ui/lub-glb/old-lub-glb-object.rs +++ b/src/test/ui/lub-glb/old-lub-glb-object.rs @@ -7,9 +7,9 @@ fn foo( x: &for<'a, 'b> Foo<&'a u8, &'b u8>, y: &for<'a> Foo<&'a u8, &'a u8>, ) { - let z = match 22 { //~ ERROR E0308 + let z = match 22 { 0 => x, - _ => y, + _ => y, //~ ERROR match arms have incompatible types }; } diff --git a/src/test/ui/lub-glb/old-lub-glb-object.stderr b/src/test/ui/lub-glb/old-lub-glb-object.stderr index 17d3648156b51..056f9131dd21c 100644 --- a/src/test/ui/lub-glb/old-lub-glb-object.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-object.stderr @@ -1,15 +1,17 @@ -error[E0308]: mismatched types - --> $DIR/old-lub-glb-object.rs:10:13 +error[E0308]: match arms have incompatible types + --> $DIR/old-lub-glb-object.rs:12:14 | -LL | let z = match 22 { //~ ERROR E0308 - | _____________^ +LL | let z = match 22 { + | _____________- LL | | 0 => x, -LL | | _ => y, + | | - this is found to be of type `&dyn for<'a, 'b> Foo<&'a u8, &'b u8>` +LL | | _ => y, //~ ERROR match arms have incompatible types + | | ^ expected bound lifetime parameter 'a, found concrete lifetime LL | | }; - | |_____^ one type is more general than the other + | |_____- `match` arms have incompatible types | - = note: expected type `dyn for<'a, 'b> Foo<&'a u8, &'b u8>` - found type `dyn for<'a> Foo<&'a u8, &'a u8>` + = note: expected type `&dyn for<'a, 'b> Foo<&'a u8, &'b u8>` + found type `&dyn for<'a> Foo<&'a u8, &'a u8>` error: aborting due to previous error diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs index 437150666be0c..521bd3695dfe5 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs @@ -7,6 +7,6 @@ fn main() { fn baz(_: F) {} fn _test<'a>(f: fn(*mut &'a u32)) { - baz(f); //~ ERROR mismatched types - //~| ERROR mismatched types + baz(f); //~ ERROR type mismatch + //~| ERROR type mismatch } diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index a6628006587c1..5dd6887005e83 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -22,25 +22,34 @@ LL | a.iter().map(|_: (u16, u16)| 45); //~ ERROR type mismatch | | | expected signature of `fn(&(u32, u32)) -> _` -error[E0308]: mismatched types +error[E0631]: type mismatch in function arguments --> $DIR/closure-arg-type-mismatch.rs:10:5 | -LL | baz(f); //~ ERROR mismatched types - | ^^^ one type is more general than the other +LL | baz(f); //~ ERROR type mismatch + | ^^^ + | | + | expected signature of `for<'r> fn(*mut &'r u32) -> _` + | found signature of `fn(*mut &'a u32) -> _` | - = note: expected type `for<'r> std::ops::Fn<(*mut &'r u32,)>` - found type `std::ops::Fn<(*mut &'a u32,)>` +note: required by `baz` + --> $DIR/closure-arg-type-mismatch.rs:8:1 + | +LL | fn baz(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0308]: mismatched types +error[E0271]: type mismatch resolving `for<'r> >::Output == ()` --> $DIR/closure-arg-type-mismatch.rs:10:5 | -LL | baz(f); //~ ERROR mismatched types - | ^^^ one type is more general than the other +LL | baz(f); //~ ERROR type mismatch + | ^^^ expected bound lifetime parameter, found concrete lifetime + | +note: required by `baz` + --> $DIR/closure-arg-type-mismatch.rs:8:1 | - = note: expected type `std::ops::FnOnce<(*mut &u32,)>` - found type `std::ops::FnOnce<(*mut &'a u32,)>` +LL | fn baz(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 5 previous errors -Some errors occurred: E0308, E0631. -For more information about an error, try `rustc --explain E0308`. +Some errors occurred: E0271, E0631. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/mismatched_types/closure-mismatch.rs b/src/test/ui/mismatched_types/closure-mismatch.rs index 152a525493732..40a4641fe7196 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.rs +++ b/src/test/ui/mismatched_types/closure-mismatch.rs @@ -5,5 +5,6 @@ impl Foo for T {} fn baz(_: T) {} fn main() { - baz(|_| ()); //~ ERROR E0308 + baz(|_| ()); //~ ERROR type mismatch + //~^ ERROR type mismatch } diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr index 0d87bc228755f..e55047e96c297 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-mismatch.stderr @@ -1,12 +1,32 @@ -error[E0308]: mismatched types +error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.rs:8:9: 8:15] as std::ops::FnOnce<(&'r (),)>>::Output == ()` --> $DIR/closure-mismatch.rs:8:5 | -LL | baz(|_| ()); //~ ERROR E0308 - | ^^^ one type is more general than the other +LL | baz(|_| ()); //~ ERROR type mismatch + | ^^^ expected bound lifetime parameter, found concrete lifetime | - = note: expected type `for<'r> std::ops::Fn<(&'r (),)>` - found type `std::ops::Fn<(&(),)>` + = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:8:9: 8:15]` +note: required by `baz` + --> $DIR/closure-mismatch.rs:5:1 + | +LL | fn baz(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/closure-mismatch.rs:8:5 + | +LL | baz(|_| ()); //~ ERROR type mismatch + | ^^^ ------ found signature of `fn(_) -> _` + | | + | expected signature of `for<'r> fn(&'r ()) -> _` + | + = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:8:9: 8:15]` +note: required by `baz` + --> $DIR/closure-mismatch.rs:5:1 + | +LL | fn baz(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors occurred: E0271, E0631. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/mismatched_types/issue-36053-2.rs b/src/test/ui/mismatched_types/issue-36053-2.rs index 9035e3380b0c5..9edfebcd49471 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.rs +++ b/src/test/ui/mismatched_types/issue-36053-2.rs @@ -7,4 +7,5 @@ fn main() { once::<&str>("str").fuse().filter(|a: &str| true).count(); //~^ ERROR no method named `count` //~| ERROR type mismatch in closure arguments + //~| ERROR type mismatch in closure arguments } diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index e53e8c520e0c4..c5c67e6bd9bd9 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -16,7 +16,15 @@ LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); | | | expected signature of `for<'r> fn(&'r &str) -> _` -error: aborting due to 2 previous errors +error[E0631]: type mismatch in closure arguments + --> $DIR/issue-36053-2.rs:7:32 + | +LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); + | ^^^^^^ -------------- found signature of `for<'r> fn(&'r str) -> _` + | | + | expected signature of `fn(&&str) -> _` + +error: aborting due to 3 previous errors Some errors occurred: E0599, E0631. For more information about an error, try `rustc --explain E0599`. diff --git a/src/test/ui/regions-fn-subtyping-return-static-fail.rs b/src/test/ui/regions-fn-subtyping-return-static-fail.rs index 242119cc201da..2dd0c9796e258 100644 --- a/src/test/ui/regions-fn-subtyping-return-static-fail.rs +++ b/src/test/ui/regions-fn-subtyping-return-static-fail.rs @@ -37,7 +37,7 @@ fn baz(x: &S) -> &S { fn supply_F() { want_F(foo); - want_F(bar); + want_F(bar); //~ ERROR mismatched types want_F(baz); } @@ -45,7 +45,7 @@ fn supply_F() { fn supply_G() { want_G(foo); want_G(bar); - want_G(baz); //~ ERROR + want_G(baz); //~ ERROR mismatched types } pub fn main() { diff --git a/src/test/ui/regions-fn-subtyping-return-static-fail.stderr b/src/test/ui/regions-fn-subtyping-return-static-fail.stderr index a9234e43191ea..66e6a615b33bc 100644 --- a/src/test/ui/regions-fn-subtyping-return-static-fail.stderr +++ b/src/test/ui/regions-fn-subtyping-return-static-fail.stderr @@ -1,12 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/regions-fn-subtyping-return-static-fail.rs:40:12 + | +LL | want_F(bar); //~ ERROR mismatched types + | ^^^ expected concrete lifetime, found bound lifetime parameter 'cx + | + = note: expected type `for<'cx> fn(&'cx S) -> &'cx S` + found type `for<'a> fn(&'a S) -> &S {bar::<'_>}` + error[E0308]: mismatched types --> $DIR/regions-fn-subtyping-return-static-fail.rs:48:12 | -LL | want_G(baz); //~ ERROR - | ^^^ one type is more general than the other +LL | want_G(baz); //~ ERROR mismatched types + | ^^^ expected concrete lifetime, found bound lifetime parameter 'cx | = note: expected type `for<'cx> fn(&'cx S) -> &'static S` - found type `for<'r> fn(&'r S) -> &'r S` + found type `for<'r> fn(&'r S) -> &'r S {baz}` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr index 47e1d0efdc77b..5c8b3d3ba6922 100644 --- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr @@ -20,10 +20,10 @@ error[E0308]: mismatched types --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43 | LL | let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR mismatched types - | ^ one type is more general than the other + | ^ expected concrete lifetime, found bound lifetime parameter | = note: expected type `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` - found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` + found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}` error: aborting due to 3 previous errors diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr index 1e7b99053f77f..f36885f7aeb99 100644 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr @@ -31,10 +31,10 @@ error[E0308]: mismatched types --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56 | LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; //~ ERROR E0308 - | ^ one type is more general than the other + | ^ expected concrete lifetime, found bound lifetime parameter | = note: expected type `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)` - found type `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)` + found type `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize) {a::<'_, '_, '_>}` error: aborting due to 4 previous errors diff --git a/src/test/ui/regions/regions-fn-subtyping-return-static.rs b/src/test/ui/regions/regions-fn-subtyping-return-static.rs index 9010770f1dc82..fa2cc37d05b2b 100644 --- a/src/test/ui/regions/regions-fn-subtyping-return-static.rs +++ b/src/test/ui/regions/regions-fn-subtyping-return-static.rs @@ -5,8 +5,6 @@ // *ANY* lifetime and returns a reference with the 'static lifetime. // This can safely be considered to be an instance of `F` because all // lifetimes are sublifetimes of 'static. -// -// compile-pass #![allow(dead_code)] #![allow(unused_variables)] @@ -40,7 +38,7 @@ fn baz(x: &S) -> &S { fn supply_F() { want_F(foo); - want_F(bar); + want_F(bar); //~ ERROR mismatched types want_F(baz); } diff --git a/src/test/ui/regions/regions-fn-subtyping-return-static.stderr b/src/test/ui/regions/regions-fn-subtyping-return-static.stderr new file mode 100644 index 0000000000000..42a5a7c806e08 --- /dev/null +++ b/src/test/ui/regions/regions-fn-subtyping-return-static.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/regions-fn-subtyping-return-static.rs:41:12 + | +LL | want_F(bar); //~ ERROR mismatched types + | ^^^ expected concrete lifetime, found bound lifetime parameter 'cx + | + = note: expected type `for<'cx> fn(&'cx S) -> &'cx S` + found type `for<'a> fn(&'a S) -> &S {bar::<'_>}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr b/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr index a43ee7ec3ace0..99d85e9e4b5a6 100644 --- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr @@ -20,10 +20,10 @@ error[E0308]: mismatched types --> $DIR/regions-lifetime-bounds-on-fns.rs:20:43 | LL | let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR E0308 - | ^ one type is more general than the other + | ^ expected concrete lifetime, found bound lifetime parameter | = note: expected type `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` - found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` + found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}` error: aborting due to 3 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs index 12626fe69cb14..a6e26614a6a50 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs @@ -11,11 +11,13 @@ fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } fn a() { let x = call_it(&square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn b() { let y = call_it_mut(&mut square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn c() { diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr index 29f276711c745..ca0298283661f 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr @@ -11,8 +11,21 @@ note: required by `call_it` LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:13 + | +LL | let x = call_it(&square, 22); + | ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` +note: required by `call_it` + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:7:1 + | +LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` - --> $DIR/unboxed-closures-unsafe-extern-fn.rs:17:13 + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:13 | LL | let y = call_it_mut(&mut square, 22); | ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` @@ -25,18 +38,31 @@ LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` - --> $DIR/unboxed-closures-unsafe-extern-fn.rs:22:13 + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:13 + | +LL | let y = call_it_mut(&mut square, 22); + | ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` +note: required by `call_it_mut` + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:8:1 + | +LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:24:13 | LL | let z = call_it_once(square, 22); | ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` | - = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` note: required by `call_it_once` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:9:1 | LL | fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs index 7c3152c87c461..dd3b1afc39f31 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs @@ -11,11 +11,13 @@ fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } fn a() { let x = call_it(&square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn b() { let y = call_it_mut(&mut square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn c() { diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr index e382457860579..0abc58aeebfe5 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr @@ -11,8 +11,21 @@ note: required by `call_it` LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` + --> $DIR/unboxed-closures-wrong-abi.rs:12:13 + | +LL | let x = call_it(&square, 22); + | ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` +note: required by `call_it` + --> $DIR/unboxed-closures-wrong-abi.rs:7:1 + | +LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-abi.rs:17:13 + --> $DIR/unboxed-closures-wrong-abi.rs:18:13 | LL | let y = call_it_mut(&mut square, 22); | ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` @@ -25,18 +38,31 @@ LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-abi.rs:22:13 + --> $DIR/unboxed-closures-wrong-abi.rs:18:13 + | +LL | let y = call_it_mut(&mut square, 22); + | ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` +note: required by `call_it_mut` + --> $DIR/unboxed-closures-wrong-abi.rs:8:1 + | +LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` + --> $DIR/unboxed-closures-wrong-abi.rs:24:13 | LL | let z = call_it_once(square, 22); | ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` | - = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` note: required by `call_it_once` --> $DIR/unboxed-closures-wrong-abi.rs:9:1 | LL | fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs index 61d46869cbbf2..c689d79266187 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs @@ -12,11 +12,13 @@ fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } fn a() { let x = call_it(&square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn b() { let y = call_it_mut(&mut square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn c() { diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr index da511f091bf6a..19b87ad171a51 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr @@ -11,8 +11,21 @@ note: required by `call_it` LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:13 + | +LL | let x = call_it(&square, 22); + | ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` +note: required by `call_it` + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:8:1 + | +LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:18:13 + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:13 | LL | let y = call_it_mut(&mut square, 22); | ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` @@ -25,18 +38,31 @@ LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:23:13 + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:13 + | +LL | let y = call_it_mut(&mut square, 22); + | ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` +note: required by `call_it_mut` + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:9:1 + | +LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:25:13 | LL | let z = call_it_once(square, 22); | ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` | - = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` note: required by `call_it_once` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:10:1 | LL | fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/where-clauses/where-for-self-2.rs b/src/test/ui/where-clauses/where-for-self-2.rs index 0ce38e69f6b0f..31174fd4cf163 100644 --- a/src/test/ui/where-clauses/where-for-self-2.rs +++ b/src/test/ui/where-clauses/where-for-self-2.rs @@ -18,5 +18,5 @@ fn foo(x: &T) {} fn main() { - foo(&X); //~ ERROR implementation of `Bar` is not general enough + foo(&X); //~ ERROR trait bound } diff --git a/src/test/ui/where-clauses/where-for-self-2.stderr b/src/test/ui/where-clauses/where-for-self-2.stderr index 342cabfd6bf0a..bbcb61a856d8d 100644 --- a/src/test/ui/where-clauses/where-for-self-2.stderr +++ b/src/test/ui/where-clauses/where-for-self-2.stderr @@ -1,12 +1,19 @@ -error: implementation of `Bar` is not general enough +error[E0277]: the trait bound `for<'a> &'a _: Bar` is not satisfied --> $DIR/where-for-self-2.rs:21:5 | -LL | foo(&X); //~ ERROR implementation of `Bar` is not general enough - | ^^^ +LL | foo(&X); //~ ERROR trait bound + | ^^^ the trait `for<'a> Bar` is not implemented for `&'a _` | - = note: Due to a where-clause on `foo`, - = note: `Bar` would have to be implemented for the type `&'0 u32`, for any lifetime `'0` - = note: but `Bar` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` + = help: the following implementations were found: + <&'static u32 as Bar> +note: required by `foo` + --> $DIR/where-for-self-2.rs:16:1 + | +LL | / fn foo(x: &T) +LL | | where for<'a> &'a T: Bar +LL | | {} + | |__^ error: aborting due to previous error +For more information about this error, try `rustc --explain E0277`.