From af5f1582b30f9e8de54e82ea9a788e8322f18f91 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 26 Feb 2021 14:54:35 +0000 Subject: [PATCH 1/6] Use tracing::instrument for better analzyabilty of logs around impl trait --- .../rustc_trait_selection/src/opaque_types.rs | 35 +++++++------------ compiler/rustc_typeck/src/check/wfcheck.rs | 6 ++-- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index d6a585e626c48..17c2ac0bd2f23 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -95,6 +95,7 @@ pub struct OpaqueTypeDecl<'tcx> { } /// Whether member constraints should be generated for all opaque types +#[derive(Debug)] pub enum GenerateMemberConstraints { /// The default, used by typeck WhenRequired, @@ -183,6 +184,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// obligations /// - `value` -- the value within which we are instantiating opaque types /// - `value_span` -- the span where the value came from, used in error reporting + #[instrument(level = "debug", skip(self))] + // FIXME(oli-obk): this function is invoked twice: once with the crate root, and then for each body that + // actually could be a defining use. It is unclear to me why we run all of it twice. Figure out what + // happens and document that or fix it. fn instantiate_opaque_types>( &self, parent_def_id: LocalDefId, @@ -191,11 +196,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { value: T, value_span: Span, ) -> InferOk<'tcx, (T, OpaqueTypeMap<'tcx>)> { - debug!( - "instantiate_opaque_types(value={:?}, parent_def_id={:?}, body_id={:?}, \ - param_env={:?}, value_span={:?})", - value, parent_def_id, body_id, param_env, value_span, - ); let mut instantiator = Instantiator { infcx: self, parent_def_id, @@ -389,6 +389,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } /// See `constrain_opaque_types` for documentation. + #[instrument(level = "debug", skip(self, free_region_relations))] fn constrain_opaque_type>( &self, def_id: DefId, @@ -396,15 +397,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { mode: GenerateMemberConstraints, free_region_relations: &FRR, ) { - debug!("constrain_opaque_type()"); - debug!("constrain_opaque_type: def_id={:?}", def_id); - debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn); - let tcx = self.tcx; let concrete_ty = self.resolve_vars_if_possible(opaque_defn.concrete_ty); - debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty); + debug!(?concrete_ty); let first_own_region = match opaque_defn.origin { hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => { @@ -469,8 +466,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }; // Compute the least upper bound of it with the other regions. - debug!("constrain_opaque_types: least_region={:?}", least_region); - debug!("constrain_opaque_types: subst_region={:?}", subst_region); + debug!(?least_region); + debug!(?subst_region); match least_region { None => least_region = Some(subst_region), Some(lr) => { @@ -997,8 +994,8 @@ struct Instantiator<'a, 'tcx> { } impl<'a, 'tcx> Instantiator<'a, 'tcx> { + #[instrument(level = "debug", skip(self))] fn instantiate_opaque_types_in_map>(&mut self, value: T) -> T { - debug!("instantiate_opaque_types_in_map(value={:?})", value); let tcx = self.infcx.tcx; value.fold_with(&mut BottomUpFolder { tcx, @@ -1075,12 +1072,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { return self.fold_opaque_ty(ty, def_id.to_def_id(), substs, origin); } - debug!( - "instantiate_opaque_types_in_map: \ - encountered opaque outside its definition scope \ - def_id={:?}", - def_id, - ); + debug!(?def_id, "encountered opaque outside its definition scope"); } } @@ -1091,6 +1083,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { }) } + #[instrument(level = "debug", skip(self))] fn fold_opaque_ty( &mut self, ty: Ty<'tcx>, @@ -1101,8 +1094,6 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let infcx = self.infcx; let tcx = infcx.tcx; - debug!("instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})", def_id, substs); - // Use the same type variable if the exact same opaque type appears more // than once in the return type (e.g., if it's passed to a type alias). if let Some(opaque_defn) = self.opaque_types.get(&def_id) { @@ -1110,7 +1101,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { return opaque_defn.concrete_ty; } let span = tcx.def_span(def_id); - debug!("fold_opaque_ty {:?} {:?}", self.value_span, span); + debug!(?self.value_span, ?span); let ty_var = infcx .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }); diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 00c6550835b43..18707f9a7a47e 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -915,6 +915,7 @@ fn check_fn_or_method<'fcx, 'tcx>( /// fn b() -> Foo { .. } /// ``` /// +#[instrument(level = "debug", skip(tcx, fcx))] fn check_opaque_types<'fcx, 'tcx>( tcx: TyCtxt<'tcx>, fcx: &FnCtxt<'fcx, 'tcx>, @@ -922,12 +923,11 @@ fn check_opaque_types<'fcx, 'tcx>( span: Span, ty: Ty<'tcx>, ) { - trace!("check_opaque_types(ty={:?})", ty); ty.fold_with(&mut ty::fold::BottomUpFolder { tcx: fcx.tcx, ty_op: |ty| { if let ty::Opaque(def_id, substs) = *ty.kind() { - trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs); + trace!(?def_id, ?substs, "opaque type"); let generics = tcx.generics_of(def_id); let opaque_hir_id = if let Some(local_id) = def_id.as_local() { @@ -965,7 +965,7 @@ fn check_opaque_types<'fcx, 'tcx>( if !may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) { return ty; } - trace!("check_opaque_types: may define, generics={:#?}", generics); + trace!(?generics, "may define"); let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default(); for (i, arg) in substs.iter().enumerate() { let arg_is_param = match arg.unpack() { From 162529698044d1c7f8dfae0f40043aaf39dad806 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 26 Feb 2021 15:18:10 +0000 Subject: [PATCH 2/6] Stop OpaqueTypeDecl from being Copy --- compiler/rustc_trait_selection/src/opaque_types.rs | 2 +- compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 17c2ac0bd2f23..1fdaeae30742e 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -21,7 +21,7 @@ pub type OpaqueTypeMap<'tcx> = DefIdMap>; /// Information about the opaque types whose values we /// are inferring in this function (these are the `impl Trait` that /// appear in the return type). -#[derive(Copy, Clone, Debug)] +#[derive(Clone, Debug)] pub struct OpaqueTypeDecl<'tcx> { /// The opaque type (`ty::Opaque`) for this declaration. pub opaque_type: Ty<'tcx>, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index dc8a804bfea98..0c29b1b4cdcba 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -399,8 +399,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - let _ = opaque_types.insert(ty, decl); let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type); + let _ = opaque_types.insert(ty, decl); } value From 549f545ce19159df0ab47f5109c042e93ff9340f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 26 Feb 2021 15:24:26 +0000 Subject: [PATCH 3/6] Require all type variables to satisfy the impl trait bounds --- .../src/borrow_check/type_check/mod.rs | 4 +- .../rustc_trait_selection/src/opaque_types.rs | 87 +++++++++++++------ compiler/rustc_typeck/src/check/check.rs | 2 +- compiler/rustc_typeck/src/check/writeback.rs | 11 ++- .../multiple-def-uses-in-one-fn.rs | 16 ++++ .../multiple-def-uses-in-one-fn.stderr | 15 ++++ 6 files changed, 100 insertions(+), 35 deletions(-) create mode 100644 src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs create mode 100644 src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index cce1549cb29c2..d1d05f8704762 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -1307,7 +1307,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { }; debug!("opaque_defn_ty = {:?}", opaque_defn_ty); let subst_opaque_defn_ty = - opaque_defn_ty.concrete_type.subst(tcx, opaque_decl.substs); + opaque_defn_ty.concrete_type.subst(tcx, opaque_decl.substs[0]); let renumbered_opaque_defn_ty = renumber::renumber_regions(infcx, subst_opaque_defn_ty); @@ -1328,7 +1328,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { opaque_def_id, ty::ResolvedOpaqueTy { concrete_type: renumbered_opaque_defn_ty, - substs: opaque_decl.substs, + substs: opaque_decl.substs[0], }, )); } else { diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 1fdaeae30742e..8678c7ba683f1 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisit use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; +use smallvec::{smallvec, SmallVec}; use std::ops::ControlFlow; @@ -37,7 +38,11 @@ pub struct OpaqueTypeDecl<'tcx> { /// fn foo<'a, 'b, T>() -> Foo<'a, T> /// /// then `substs` would be `['a, T]`. - pub substs: SubstsRef<'tcx>, + /// + /// In case there are multiple conflicting substs an error has already + /// been reported, but we still store the additional substs here in order + /// to allow for better diagnostics later. + pub substs: SmallVec<[SubstsRef<'tcx>; 1]>, /// The span of this particular definition of the opaque type. So /// for example: @@ -429,11 +434,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // If there are required region bounds, we can use them. if opaque_defn.has_required_region_bounds { let bounds = tcx.explicit_item_bounds(def_id); - debug!("constrain_opaque_type: predicates: {:#?}", bounds); + debug!(?bounds, "predicates"); let bounds: Vec<_> = - bounds.iter().map(|(bound, _)| bound.subst(tcx, opaque_defn.substs)).collect(); - debug!("constrain_opaque_type: bounds={:#?}", bounds); - let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs); + bounds.iter().map(|(bound, _)| bound.subst(tcx, opaque_defn.substs[0])).collect(); + debug!(?bounds); + let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs[0]); let required_region_bounds = required_region_bounds(tcx, opaque_type, bounds.into_iter()); @@ -459,7 +464,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // second. let mut least_region = None; - for subst_arg in &opaque_defn.substs[first_own_region..] { + for subst_arg in &opaque_defn.substs[0][first_own_region..] { let subst_region = match subst_arg.unpack() { GenericArgKind::Lifetime(r) => r, GenericArgKind::Type(_) | GenericArgKind::Const(_) => continue, @@ -532,7 +537,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // type can be equal to any of the region parameters of the // opaque type definition. let choice_regions: Lrc>> = Lrc::new( - opaque_defn.substs[first_own_region..] + opaque_defn.substs[0][first_own_region..] .iter() .filter_map(|arg| match arg.unpack() { GenericArgKind::Lifetime(r) => Some(r), @@ -1095,10 +1100,32 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let tcx = infcx.tcx; // Use the same type variable if the exact same opaque type appears more - // than once in the return type (e.g., if it's passed to a type alias). - if let Some(opaque_defn) = self.opaque_types.get(&def_id) { - debug!("instantiate_opaque_types: returning concrete ty {:?}", opaque_defn.concrete_ty); - return opaque_defn.concrete_ty; + // than once in a function (e.g., if it's passed to a type alias). + if let Some(opaque_defn) = self.opaque_types.get_mut(&def_id) { + debug!(?opaque_defn, "found already known concrete type"); + if opaque_defn.substs.contains(&substs) { + // Already seen this concrete type + return opaque_defn.concrete_ty; + } else { + // Don't emit multiple errors for the same set of substs + opaque_defn.substs.push(substs); + tcx.sess + .struct_span_err( + self.value_span, + &format!( + "defining use generics {:?} differ from previous defining use", + substs + ), + ) + .span_note( + opaque_defn.definition_span, + &format!( + "previous defining use with different generics {:?} found here", + opaque_defn.substs[0] + ), + ) + .delay_as_bug(); + } } let span = tcx.def_span(def_id); debug!(?self.value_span, ?span); @@ -1106,7 +1133,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }); let item_bounds = tcx.explicit_item_bounds(def_id); - debug!("instantiate_opaque_types: bounds={:#?}", item_bounds); + debug!(?item_bounds); let bounds: Vec<_> = item_bounds.iter().map(|(bound, _)| bound.subst(tcx, substs)).collect(); @@ -1115,16 +1142,16 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { infcx.partially_normalize_associated_types_in(span, self.body_id, param_env, bounds); self.obligations.extend(obligations); - debug!("instantiate_opaque_types: bounds={:?}", bounds); + debug!(?bounds); let required_region_bounds = required_region_bounds(tcx, ty, bounds.iter().copied()); - debug!("instantiate_opaque_types: required_region_bounds={:?}", required_region_bounds); + debug!(?required_region_bounds); // Make sure that we are in fact defining the *entire* type // (e.g., `type Foo = impl Bar;` needs to be // defined by a function like `fn foo() -> Foo`). - debug!("instantiate_opaque_types: param_env={:#?}", self.param_env,); - debug!("instantiate_opaque_types: generics={:#?}", tcx.generics_of(def_id),); + debug!(?self.param_env,); + debug!(generics= ?tcx.generics_of(def_id),); // Ideally, we'd get the span where *this specific `ty` came // from*, but right now we just use the span from the overall @@ -1133,18 +1160,22 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { // Foo, impl Bar)`. let definition_span = self.value_span; - self.opaque_types.insert( - def_id, - OpaqueTypeDecl { - opaque_type: ty, - substs, - definition_span, - concrete_ty: ty_var, - has_required_region_bounds: !required_region_bounds.is_empty(), - origin, - }, - ); - debug!("instantiate_opaque_types: ty_var={:?}", ty_var); + // We only keep the first concrete type var, as we will already error + // out if there are multiple due to the conflicting obligations + if !self.opaque_types.contains_key(&def_id) { + self.opaque_types.insert( + def_id, + OpaqueTypeDecl { + opaque_type: ty, + substs: smallvec![substs], + definition_span, + concrete_ty: ty_var, + has_required_region_bounds: !required_region_bounds.is_empty(), + origin, + }, + ); + } + debug!(?ty_var); for predicate in &bounds { if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() { diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index e2fc1da5c786c..310c3f13a244c 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -741,7 +741,7 @@ fn check_opaque_meets_bounds<'tcx>( for (def_id, opaque_defn) in opaque_type_map { match infcx .at(&misc_cause, param_env) - .eq(opaque_defn.concrete_ty, tcx.type_of(def_id).subst(tcx, opaque_defn.substs)) + .eq(opaque_defn.concrete_ty, tcx.type_of(def_id).subst(tcx, opaque_defn.substs[0])) { Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok), Err(ty_err) => tcx.sess.delay_span_bug( diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index d3866df44ff31..2fd83dde0fe2f 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -515,7 +515,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // figures out the concrete type with `U`, but the stored type is with `T`. let definition_ty = self.fcx.infer_opaque_definition_from_instantiation( def_id, - opaque_defn.substs, + opaque_defn.substs[0], instantiated_ty, span, ); @@ -535,7 +535,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } - if !opaque_defn.substs.needs_infer() { + if !opaque_defn.substs[0].needs_infer() { // We only want to add an entry into `concrete_opaque_types` // if we actually found a defining usage of this opaque type. // Otherwise, we do nothing - we'll either find a defining usage @@ -544,12 +544,15 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { if !skip_add { let new = ty::ResolvedOpaqueTy { concrete_type: definition_ty, - substs: opaque_defn.substs, + substs: opaque_defn.substs[0], }; + debug!(?def_id, ?new, "inserting opaque type resolution"); let old = self.typeck_results.concrete_opaque_types.insert(def_id, new); if let Some(old) = old { - if old.concrete_type != definition_ty || old.substs != opaque_defn.substs { + debug!(?old, "duplicate insertion"); + if old.concrete_type != definition_ty || old.substs != opaque_defn.substs[0] + { span_bug!( span, "`visit_opaque_types` tried to write different types for the same \ diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs new file mode 100644 index 0000000000000..ca3cbecb09dad --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/73481 +// This test used to cause unsoundness, since one of the two possible +// resolutions was chosen at random instead of erroring due to conflicts. + +#![feature(min_type_alias_impl_trait)] + +type X = impl Into<&'static A>; +//~^ the trait bound `&'static B: From<&A>` is not satisfied + +fn f(a: &'static A, b: B) -> (X, X) { + (a, a) +} + +fn main() { + println!("{}", as Into<&String>>::into(f(&[1isize, 2, 3], String::new()).1)); +} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr new file mode 100644 index 0000000000000..731c6e2788dde --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied + --> $DIR/multiple-def-uses-in-one-fn.rs:7:16 + | +LL | type X = impl Into<&'static A>; + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B` + | + = note: required because of the requirements on the impl of `Into<&'static B>` for `&A` +help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement + | +LL | fn f(a: &'static A, b: B) -> (X, X) where &'static B: From<&A> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From d9d4a520932d1a49149899e0edbb90b3e1153728 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 26 Feb 2021 17:29:09 +0000 Subject: [PATCH 4/6] Emit an error when there are two differently inferred impl traits within a single function --- .../rustc_trait_selection/src/opaque_types.rs | 12 ++++-- .../multiple-def-uses-in-one-fn-pass.rs | 12 ++++++ .../multiple-def-uses-in-one-fn.rs | 4 +- .../multiple-def-uses-in-one-fn.stderr | 26 +++++++++++- .../multiple-def-uses-in-one-fn2.rs | 17 ++++++++ .../multiple-def-uses-in-one-fn2.stderr | 26 ++++++++++++ .../multiple-def-uses-in-one-fn3.rs | 19 +++++++++ .../multiple-def-uses-in-one-fn3.stderr | 42 +++++++++++++++++++ 8 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs create mode 100644 src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs create mode 100644 src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr create mode 100644 src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs create mode 100644 src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 8678c7ba683f1..12787557303a1 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -1109,22 +1109,26 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { } else { // Don't emit multiple errors for the same set of substs opaque_defn.substs.push(substs); + /*opaque_defn.concrete_ty = tcx.ty_error_with_message( + self.value_span, + "defining use generics differ from previous defining use", + );*/ tcx.sess .struct_span_err( self.value_span, &format!( - "defining use generics {:?} differ from previous defining use", + "defining use generics `{:?}` differ from previous defining use", substs ), ) .span_note( opaque_defn.definition_span, &format!( - "previous defining use with different generics {:?} found here", + "previous defining use with different generics `{:?}` found here", opaque_defn.substs[0] ), ) - .delay_as_bug(); + .emit(); } } let span = tcx.def_span(def_id); @@ -1161,7 +1165,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let definition_span = self.value_span; // We only keep the first concrete type var, as we will already error - // out if there are multiple due to the conflicting obligations + // out if there are multiple due to the conflicting obligations if !self.opaque_types.contains_key(&def_id) { self.opaque_types.insert( def_id, diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs new file mode 100644 index 0000000000000..ecad910f7d542 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs @@ -0,0 +1,12 @@ +// check-pass +#![feature(min_type_alias_impl_trait)] + +type X = impl ToString; + +fn f(a: A, b: B) -> (X, X) { + (a.clone(), a) +} + +fn main() { + println!("{}", as ToString>::to_string(&f(42_i32, String::new()).1)); +} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs index ca3cbecb09dad..66ca81a817f17 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs @@ -5,9 +5,11 @@ #![feature(min_type_alias_impl_trait)] type X = impl Into<&'static A>; -//~^ the trait bound `&'static B: From<&A>` is not satisfied +//~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied fn f(a: &'static A, b: B) -> (X, X) { + //~^ ERROR defining use generics `[B, A]` differ from previous defining use + //~| ERROR defining use generics `[B, A]` differ from previous defining use (a, a) } diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr index 731c6e2788dde..bfdd1ad0dedf9 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr @@ -1,3 +1,15 @@ +error: defining use generics `[B, A]` differ from previous defining use + --> $DIR/multiple-def-uses-in-one-fn.rs:10:45 + | +LL | fn f(a: &'static A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^ + | +note: previous defining use with different generics `[A, B]` found here + --> $DIR/multiple-def-uses-in-one-fn.rs:10:45 + | +LL | fn f(a: &'static A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^ + error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied --> $DIR/multiple-def-uses-in-one-fn.rs:7:16 | @@ -10,6 +22,18 @@ help: consider introducing a `where` bound, but there might be an alternative be LL | fn f(a: &'static A, b: B) -> (X, X) where &'static B: From<&A> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: defining use generics `[B, A]` differ from previous defining use + --> $DIR/multiple-def-uses-in-one-fn.rs:10:1 + | +LL | fn f(a: &'static A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: previous defining use with different generics `[A, B]` found here + --> $DIR/multiple-def-uses-in-one-fn.rs:10:1 + | +LL | fn f(a: &'static A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs new file mode 100644 index 0000000000000..9254222651d48 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs @@ -0,0 +1,17 @@ +// https://github.com/rust-lang/rust/issues/73481 +// This test used to cause unsoundness, since one of the two possible +// resolutions was chosen at random instead of erroring due to conflicts. + +#![feature(min_type_alias_impl_trait)] + +type X = impl ToString; + +fn f(a: A, b: B) -> (X, X) { + //~^ ERROR defining use generics `[B, A]` differ from previous defining use + //~| ERROR defining use generics `[B, A]` differ from previous defining use + (a.clone(), a) +} + +fn main() { + println!("{}", as ToString>::to_string(&f(42_i32, String::new()).1)); +} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr new file mode 100644 index 0000000000000..d4fd38b752251 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr @@ -0,0 +1,26 @@ +error: defining use generics `[B, A]` differ from previous defining use + --> $DIR/multiple-def-uses-in-one-fn2.rs:9:63 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^ + | +note: previous defining use with different generics `[A, B]` found here + --> $DIR/multiple-def-uses-in-one-fn2.rs:9:63 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^ + +error: defining use generics `[B, A]` differ from previous defining use + --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: previous defining use with different generics `[A, B]` found here + --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs new file mode 100644 index 0000000000000..68a14c80bd990 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs @@ -0,0 +1,19 @@ +// https://github.com/rust-lang/rust/issues/73481 +// This test used to cause unsoundness, since one of the two possible +// resolutions was chosen at random instead of erroring due to conflicts. + +#![feature(min_type_alias_impl_trait)] + +type X = impl ToString; + +fn f(a: A, b: B) -> (X, X) { + //~^ ERROR defining use generics `[B, A]` differ from previous defining use + //~| ERROR defining use generics `[B, A]` differ from previous defining use + (a, b) +} + +fn g(a: A, b: B) -> (X, X) { + (a, b) //~ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr new file mode 100644 index 0000000000000..fecf1832e2f7a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr @@ -0,0 +1,42 @@ +error: defining use generics `[B, A]` differ from previous defining use + --> $DIR/multiple-def-uses-in-one-fn3.rs:9:63 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^ + | +note: previous defining use with different generics `[A, B]` found here + --> $DIR/multiple-def-uses-in-one-fn3.rs:9:63 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^ + +error: defining use generics `[B, A]` differ from previous defining use + --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: previous defining use with different generics `[A, B]` found here + --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/multiple-def-uses-in-one-fn3.rs:16:9 + | +LL | fn g(a: A, b: B) -> (X, X) { + | - - found type parameter + | | + | expected type parameter +LL | (a, b) + | ^ expected type parameter `A`, found type parameter `B` + | + = note: expected type parameter `A` + found type parameter `B` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. From 0382c00f9c877f1f634e3bae7530bb43eac03a2a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 18 Mar 2021 10:28:30 +0000 Subject: [PATCH 5/6] Defining use errors yield the error type to reduce irrelevant follow-up diagnostics --- .../rustc_trait_selection/src/opaque_types.rs | 4 ++-- .../multiple-def-uses-in-one-fn.rs | 1 - .../multiple-def-uses-in-one-fn.stderr | 23 ++++--------------- .../multiple-def-uses-in-one-fn3.rs | 1 + .../multiple-def-uses-in-one-fn3.stderr | 17 ++++++++++++-- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 12787557303a1..eec66d154b2d2 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -1109,10 +1109,10 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { } else { // Don't emit multiple errors for the same set of substs opaque_defn.substs.push(substs); - /*opaque_defn.concrete_ty = tcx.ty_error_with_message( + opaque_defn.concrete_ty = tcx.ty_error_with_message( self.value_span, "defining use generics differ from previous defining use", - );*/ + ); tcx.sess .struct_span_err( self.value_span, diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs index 66ca81a817f17..44f85df4d6cb8 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs @@ -5,7 +5,6 @@ #![feature(min_type_alias_impl_trait)] type X = impl Into<&'static A>; -//~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied fn f(a: &'static A, b: B) -> (X, X) { //~^ ERROR defining use generics `[B, A]` differ from previous defining use diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr index bfdd1ad0dedf9..55c4d8de9502c 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr @@ -1,39 +1,26 @@ error: defining use generics `[B, A]` differ from previous defining use - --> $DIR/multiple-def-uses-in-one-fn.rs:10:45 + --> $DIR/multiple-def-uses-in-one-fn.rs:9:45 | LL | fn f(a: &'static A, b: B) -> (X, X) { | ^^^^^^^^^^^^^^^^^^ | note: previous defining use with different generics `[A, B]` found here - --> $DIR/multiple-def-uses-in-one-fn.rs:10:45 + --> $DIR/multiple-def-uses-in-one-fn.rs:9:45 | LL | fn f(a: &'static A, b: B) -> (X, X) { | ^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied - --> $DIR/multiple-def-uses-in-one-fn.rs:7:16 - | -LL | type X = impl Into<&'static A>; - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B` - | - = note: required because of the requirements on the impl of `Into<&'static B>` for `&A` -help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement - | -LL | fn f(a: &'static A, b: B) -> (X, X) where &'static B: From<&A> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: defining use generics `[B, A]` differ from previous defining use - --> $DIR/multiple-def-uses-in-one-fn.rs:10:1 + --> $DIR/multiple-def-uses-in-one-fn.rs:9:1 | LL | fn f(a: &'static A, b: B) -> (X, X) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previous defining use with different generics `[A, B]` found here - --> $DIR/multiple-def-uses-in-one-fn.rs:10:1 + --> $DIR/multiple-def-uses-in-one-fn.rs:9:1 | LL | fn f(a: &'static A, b: B) -> (X, X) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs index 68a14c80bd990..2f5120dc23e9c 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs @@ -13,6 +13,7 @@ fn f(a: A, b: B) -> (X, X) } fn g(a: A, b: B) -> (X, X) { + //~^ ERROR concrete type differs from previous defining opaque type use (a, b) //~ ERROR mismatched types } diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr index fecf1832e2f7a..df55300f35399 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr @@ -23,12 +23,13 @@ LL | fn f(a: A, b: B) -> (X, X $DIR/multiple-def-uses-in-one-fn3.rs:16:9 + --> $DIR/multiple-def-uses-in-one-fn3.rs:17:9 | LL | fn g(a: A, b: B) -> (X, X) { | - - found type parameter | | | expected type parameter +LL | LL | (a, b) | ^ expected type parameter `A`, found type parameter `B` | @@ -37,6 +38,18 @@ LL | (a, b) = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -error: aborting due to 3 previous errors +error: concrete type differs from previous defining opaque type use + --> $DIR/multiple-def-uses-in-one-fn3.rs:15:1 + | +LL | fn g(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `[type error]`, got `A` + | +note: previous use here + --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. From 93f3d0867ed9a1ad343356955c314b3df8fd99f0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 18 Mar 2021 10:49:37 +0000 Subject: [PATCH 6/6] Don't emit errors containing `type error` as another (more useful) error must have been emitted already --- compiler/rustc_typeck/src/collect/type_of.rs | 5 ++++- .../ui/generator/layout-error.min_tait.stderr | 14 +------------- src/test/ui/generator/layout-error.rs | 1 - ...adata-sufficient-for-layout.full_tait.stderr | 2 +- ...tadata-sufficient-for-layout.min_tait.stderr | 14 +------------- .../generator/metadata-sufficient-for-layout.rs | 1 - ...ssue-52843-closure-constrain.min_tait.stderr | 14 +------------- .../issue-52843-closure-constrain.rs | 2 +- .../issue-60407.min_tait.stderr | 14 +------------- .../ui/type-alias-impl-trait/issue-60407.rs | 2 +- .../multiple-def-uses-in-one-fn3.rs | 1 - .../multiple-def-uses-in-one-fn3.stderr | 17 ++--------------- 12 files changed, 13 insertions(+), 74 deletions(-) diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 3f2f244e44fd2..5dbe425b1c169 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -540,7 +540,10 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } if let Some((prev_span, prev_ty)) = self.found { - if *concrete_type != prev_ty { + if *concrete_type != prev_ty + && !concrete_type.references_error() + && !prev_ty.references_error() + { debug!("find_opaque_ty_constraints: span={:?}", span); // Found different concrete types for the opaque type. let mut err = self.tcx.sess.struct_span_err( diff --git a/src/test/ui/generator/layout-error.min_tait.stderr b/src/test/ui/generator/layout-error.min_tait.stderr index be469d781b5c6..1a8518391e6bb 100644 --- a/src/test/ui/generator/layout-error.min_tait.stderr +++ b/src/test/ui/generator/layout-error.min_tait.stderr @@ -22,19 +22,7 @@ LL | static POOL: Task = Task::new(); = note: see issue #63065 for more information = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable -error: concrete type differs from previous defining opaque type use - --> $DIR/layout-error.rs:31:24 - | -LL | Task::spawn(&POOL, || cb()); - | ^^^^^^^ expected `[type error]`, got `impl Future` - | -note: previous use here - --> $DIR/layout-error.rs:30:5 - | -LL | static POOL: Task = Task::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0425, E0658. For more information about an error, try `rustc --explain E0425`. diff --git a/src/test/ui/generator/layout-error.rs b/src/test/ui/generator/layout-error.rs index 9f15a6b2eca00..0588bcd3a57ac 100644 --- a/src/test/ui/generator/layout-error.rs +++ b/src/test/ui/generator/layout-error.rs @@ -29,5 +29,4 @@ fn main() { // Check that statics are inhabited computes they layout. static POOL: Task = Task::new(); //[min_tait]~ ERROR not permitted here Task::spawn(&POOL, || cb()); //[min_tait]~ ERROR type alias impl trait is not permitted here - //[min_tait]~^ ERROR concrete type differs from previous } diff --git a/src/test/ui/generator/metadata-sufficient-for-layout.full_tait.stderr b/src/test/ui/generator/metadata-sufficient-for-layout.full_tait.stderr index ce874c1518c0e..724ac3ba861a5 100644 --- a/src/test/ui/generator/metadata-sufficient-for-layout.full_tait.stderr +++ b/src/test/ui/generator/metadata-sufficient-for-layout.full_tait.stderr @@ -16,7 +16,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_binding = note: see issue #63065 for more information error: fatal error triggered by #[rustc_error] - --> $DIR/metadata-sufficient-for-layout.rs:29:1 + --> $DIR/metadata-sufficient-for-layout.rs:28:1 | LL | fn main() {} | ^^^^^^^^^ diff --git a/src/test/ui/generator/metadata-sufficient-for-layout.min_tait.stderr b/src/test/ui/generator/metadata-sufficient-for-layout.min_tait.stderr index e2b0d3622a600..5c13b2dbef512 100644 --- a/src/test/ui/generator/metadata-sufficient-for-layout.min_tait.stderr +++ b/src/test/ui/generator/metadata-sufficient-for-layout.min_tait.stderr @@ -7,18 +7,6 @@ LL | static A: Option = None; = note: see issue #63065 for more information = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable -error: concrete type differs from previous defining opaque type use - --> $DIR/metadata-sufficient-for-layout.rs:25:1 - | -LL | fn f() -> F { metadata_sufficient_for_layout::g() } - | ^^^^^^^^^^^ expected `[type error]`, got `impl Generator` - | -note: previous use here - --> $DIR/metadata-sufficient-for-layout.rs:22:1 - | -LL | static A: Option = None; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/generator/metadata-sufficient-for-layout.rs b/src/test/ui/generator/metadata-sufficient-for-layout.rs index f206093d9710c..1cb01d9ea8425 100644 --- a/src/test/ui/generator/metadata-sufficient-for-layout.rs +++ b/src/test/ui/generator/metadata-sufficient-for-layout.rs @@ -23,7 +23,6 @@ static A: Option = None; //[min_tait]~^ ERROR not permitted here fn f() -> F { metadata_sufficient_for_layout::g() } -//[min_tait]~^ ERROR concrete type differs #[rustc_error] fn main() {} //[full_tait]~ ERROR diff --git a/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.min_tait.stderr index c2cb4829fb78a..36e6cf578e0db 100644 --- a/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.min_tait.stderr @@ -7,18 +7,6 @@ LL | let null = || -> Opaque { 0 }; = note: see issue #63063 for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable -error: concrete type differs from previous defining opaque type use - --> $DIR/issue-52843-closure-constrain.rs:13:16 - | -LL | let null = || -> Opaque { 0 }; - | ^^^^^^^^^^^^^^^^^^ expected `String`, got `[type error]` - | -note: previous use here - --> $DIR/issue-52843-closure-constrain.rs:12:5 - | -LL | fn _unused() -> Opaque { String::new() } - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs index 01f874155fa1e..71e9add61978a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs +++ b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs @@ -11,6 +11,6 @@ fn main() { type Opaque = impl Debug; fn _unused() -> Opaque { String::new() } let null = || -> Opaque { 0 }; //[min_tait]~ ERROR: not permitted here - //~^ ERROR: concrete type differs from previous defining opaque type use + //[full_tait]~^ ERROR: concrete type differs from previous defining opaque type use println!("{:?}", null()); } diff --git a/src/test/ui/type-alias-impl-trait/issue-60407.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-60407.min_tait.stderr index edb8141c1b104..4f02b2ee60ab5 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60407.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60407.min_tait.stderr @@ -7,18 +7,6 @@ LL | static mut TEST: Option = None; = note: see issue #63065 for more information = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable -error: concrete type differs from previous defining opaque type use - --> $DIR/issue-60407.rs:16:1 - | -LL | fn foo() -> Debuggable { - | ^^^^^^^^^^^^^^^^^^^^^^ expected `[type error]`, got `u32` - | -note: previous use here - --> $DIR/issue-60407.rs:9:1 - | -LL | static mut TEST: Option = None; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/type-alias-impl-trait/issue-60407.rs b/src/test/ui/type-alias-impl-trait/issue-60407.rs index afcbf313cc855..2a8e3f7a0bf1a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60407.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60407.rs @@ -13,6 +13,6 @@ fn main() { //[full_tait]~ ERROR unsafe { TEST = Some(foo()) } } -fn foo() -> Debuggable { //[min_tait]~ ERROR concrete type differs +fn foo() -> Debuggable { 0u32 } diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs index 2f5120dc23e9c..68a14c80bd990 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs @@ -13,7 +13,6 @@ fn f(a: A, b: B) -> (X, X) } fn g(a: A, b: B) -> (X, X) { - //~^ ERROR concrete type differs from previous defining opaque type use (a, b) //~ ERROR mismatched types } diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr index df55300f35399..fecf1832e2f7a 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr @@ -23,13 +23,12 @@ LL | fn f(a: A, b: B) -> (X, X $DIR/multiple-def-uses-in-one-fn3.rs:17:9 + --> $DIR/multiple-def-uses-in-one-fn3.rs:16:9 | LL | fn g(a: A, b: B) -> (X, X) { | - - found type parameter | | | expected type parameter -LL | LL | (a, b) | ^ expected type parameter `A`, found type parameter `B` | @@ -38,18 +37,6 @@ LL | (a, b) = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-def-uses-in-one-fn3.rs:15:1 - | -LL | fn g(a: A, b: B) -> (X, X) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `[type error]`, got `A` - | -note: previous use here - --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1 - | -LL | fn f(a: A, b: B) -> (X, X) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`.