diff --git a/RELEASES.md b/RELEASES.md index aae2a66965014..a9422fa103ed8 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -156,6 +156,7 @@ Language - [Macro attributes may follow `#[derive]` and will see the original (pre-`cfg`) input.][87220] - [Accept curly-brace macros in expressions, like `m!{ .. }.method()` and `m!{ .. }?`.][88690] - [Allow panicking in constant evaluation.][89508] +- [Ignore derived `Clone` and `Debug` implementations during dead code analysis.][85200] Compiler -------- @@ -216,6 +217,9 @@ Cargo Compatibility notes ------------------- +- [Ignore derived `Clone` and `Debug` implementations during dead code analysis.][85200] + This will break some builds that set `#![deny(dead_code)]`. + Internal changes ---------------- These changes provide no direct user facing benefits, but represent significant @@ -224,6 +228,7 @@ and related tools. - [Added an experimental backend for codegen with `libgccjit`.][87260] +[85200]: https://github.com/rust-lang/rust/pull/85200/ [86191]: https://github.com/rust-lang/rust/pull/86191/ [87220]: https://github.com/rust-lang/rust/pull/87220/ [87260]: https://github.com/rust-lang/rust/pull/87260/ diff --git a/compiler/rustc_ast_pretty/src/pp/convenience.rs b/compiler/rustc_ast_pretty/src/pp/convenience.rs index 785e6886d8a38..93310dd45c575 100644 --- a/compiler/rustc_ast_pretty/src/pp/convenience.rs +++ b/compiler/rustc_ast_pretty/src/pp/convenience.rs @@ -75,6 +75,10 @@ impl Printer { } pub fn trailing_comma(&mut self) { + self.scan_break(BreakToken { pre_break: Some(','), ..BreakToken::default() }); + } + + pub fn trailing_comma_or_space(&mut self) { self.scan_break(BreakToken { blank_space: 1, pre_break: Some(','), diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 44116fa76a0c1..6435f1b6141e3 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -142,7 +142,7 @@ impl<'a> State<'a> { if !field.is_last || has_rest { self.word_space(","); } else { - self.trailing_comma(); + self.trailing_comma_or_space(); } } if has_rest { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index dac84ae9d5fc8..d7e9ef0e50dd8 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -1,5 +1,6 @@ use crate::pp::Breaks::Inconsistent; -use crate::pprust::state::{AnnNode, PrintState, State}; +use crate::pprust::state::delimited::IterDelimited; +use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT}; use rustc_ast as ast; use rustc_ast::GenericBound; @@ -138,11 +139,10 @@ impl<'a> State<'a> { self.end(); // end outer head-block } ast::ItemKind::Use(ref tree) => { - self.head(visibility_qualified(&item.vis, "use")); + self.print_visibility(&item.vis); + self.word_nbsp("use"); self.print_use_tree(tree); self.word(";"); - self.end(); // end inner head-block - self.end(); // end outer head-block } ast::ItemKind::Static(ref ty, mutbl, ref body) => { let def = ast::Defaultness::Final; @@ -615,8 +615,8 @@ impl<'a> State<'a> { ast::UseTreeKind::Simple(rename, ..) => { self.print_path(&tree.prefix, false, 0); if let Some(rename) = rename { - self.space(); - self.word_space("as"); + self.nbsp(); + self.word_nbsp("as"); self.print_ident(rename); } } @@ -628,16 +628,36 @@ impl<'a> State<'a> { self.word("*"); } ast::UseTreeKind::Nested(ref items) => { - if tree.prefix.segments.is_empty() { - self.word("{"); - } else { + if !tree.prefix.segments.is_empty() { self.print_path(&tree.prefix, false, 0); - self.word("::{"); + self.word("::"); + } + if items.is_empty() { + self.word("{}"); + } else if items.len() == 1 { + self.print_use_tree(&items[0].0); + } else { + self.cbox(INDENT_UNIT); + self.word("{"); + self.zerobreak(); + self.ibox(0); + for use_tree in items.iter().delimited() { + self.print_use_tree(&use_tree.0); + if !use_tree.is_last { + self.word(","); + if let ast::UseTreeKind::Nested(_) = use_tree.0.kind { + self.hardbreak(); + } else { + self.space(); + } + } + } + self.end(); + self.trailing_comma(); + self.offset(-INDENT_UNIT); + self.word("}"); + self.end(); } - self.commasep(Inconsistent, &items, |this, &(ref tree, _)| { - this.print_use_tree(tree) - }); - self.word("}"); } } } diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index c401f65eddaed..a72681dbf4e7e 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -97,6 +97,7 @@ E0184: include_str!("./error_codes/E0184.md"), E0185: include_str!("./error_codes/E0185.md"), E0186: include_str!("./error_codes/E0186.md"), E0191: include_str!("./error_codes/E0191.md"), +E0192: include_str!("./error_codes/E0192.md"), E0193: include_str!("./error_codes/E0193.md"), E0195: include_str!("./error_codes/E0195.md"), E0197: include_str!("./error_codes/E0197.md"), @@ -522,7 +523,6 @@ E0787: include_str!("./error_codes/E0787.md"), // E0188, // can not cast an immutable reference to a mutable pointer // E0189, // deprecated: can only cast a boxed pointer to a boxed object // E0190, // deprecated: can only cast a &-pointer to an &-object -// E0192, // negative impl only applicable to auto traits // E0194, // merged into E0403 // E0196, // cannot determine a type for this closure E0208, diff --git a/compiler/rustc_error_codes/src/error_codes/E0192.md b/compiler/rustc_error_codes/src/error_codes/E0192.md index 5fd951b2e86cb..deca042a91a50 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0192.md +++ b/compiler/rustc_error_codes/src/error_codes/E0192.md @@ -1,15 +1,17 @@ +#### Note: this error code is no longer emitted by the compiler. + A negative impl was added on a trait implementation. Erroneous code example: -```compile_fail,E0192 +```compile_fail trait Trait { type Bar; } struct Foo; -impl !Trait for Foo { } //~ ERROR E0192 +impl !Trait for Foo { } //~ ERROR fn main() {} ``` diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 9d40b3cba2952..bd5892dba38c7 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -49,6 +49,31 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { Canonicalizer::canonicalize(value, self, self.tcx, &CanonicalizeAllFreeRegions, query_state) } + /// Like [Self::canonicalize_query], but preserves distinct universes. For + /// example, canonicalizing `&'?0: Trait<'?1>`, where `'?0` is in `U1` and + /// `'?1` is in `U3` would be canonicalized to have ?0` in `U1` and `'?1` + /// in `U2`. + /// + /// This is used for Chalk integration. + pub fn canonicalize_query_preserving_universes( + &self, + value: V, + query_state: &mut OriginalQueryValues<'tcx>, + ) -> Canonicalized<'tcx, V> + where + V: TypeFoldable<'tcx>, + { + self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); + + Canonicalizer::canonicalize( + value, + self, + self.tcx, + &CanonicalizeAllFreeRegionsPreservingUniverses, + query_state, + ) + } + /// Canonicalizes a query *response* `V`. When we canonicalize a /// query response, we only canonicalize unbound inference /// variables, and we leave other free regions alone. So, @@ -133,7 +158,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// maximally general query. But if we are canonicalizing a *query /// response*, then we don't typically replace free regions, as they /// must have been introduced from other parts of the system. -trait CanonicalizeRegionMode { +trait CanonicalizeMode { fn canonicalize_free_region<'tcx>( &self, canonicalizer: &mut Canonicalizer<'_, 'tcx>, @@ -141,11 +166,14 @@ trait CanonicalizeRegionMode { ) -> ty::Region<'tcx>; fn any(&self) -> bool; + + // Do we preserve universe of variables. + fn preserve_universes(&self) -> bool; } struct CanonicalizeQueryResponse; -impl CanonicalizeRegionMode for CanonicalizeQueryResponse { +impl CanonicalizeMode for CanonicalizeQueryResponse { fn canonicalize_free_region<'tcx>( &self, canonicalizer: &mut Canonicalizer<'_, 'tcx>, @@ -198,11 +226,15 @@ impl CanonicalizeRegionMode for CanonicalizeQueryResponse { fn any(&self) -> bool { false } + + fn preserve_universes(&self) -> bool { + true + } } struct CanonicalizeUserTypeAnnotation; -impl CanonicalizeRegionMode for CanonicalizeUserTypeAnnotation { +impl CanonicalizeMode for CanonicalizeUserTypeAnnotation { fn canonicalize_free_region<'tcx>( &self, canonicalizer: &mut Canonicalizer<'_, 'tcx>, @@ -221,11 +253,15 @@ impl CanonicalizeRegionMode for CanonicalizeUserTypeAnnotation { fn any(&self) -> bool { false } + + fn preserve_universes(&self) -> bool { + false + } } struct CanonicalizeAllFreeRegions; -impl CanonicalizeRegionMode for CanonicalizeAllFreeRegions { +impl CanonicalizeMode for CanonicalizeAllFreeRegions { fn canonicalize_free_region<'tcx>( &self, canonicalizer: &mut Canonicalizer<'_, 'tcx>, @@ -237,11 +273,39 @@ impl CanonicalizeRegionMode for CanonicalizeAllFreeRegions { fn any(&self) -> bool { true } + + fn preserve_universes(&self) -> bool { + false + } +} + +struct CanonicalizeAllFreeRegionsPreservingUniverses; + +impl CanonicalizeMode for CanonicalizeAllFreeRegionsPreservingUniverses { + fn canonicalize_free_region<'tcx>( + &self, + canonicalizer: &mut Canonicalizer<'_, 'tcx>, + r: ty::Region<'tcx>, + ) -> ty::Region<'tcx> { + let universe = canonicalizer.infcx.universe_of_region(r); + canonicalizer.canonical_var_for_region( + CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) }, + r, + ) + } + + fn any(&self) -> bool { + true + } + + fn preserve_universes(&self) -> bool { + true + } } struct CanonicalizeFreeRegionsOtherThanStatic; -impl CanonicalizeRegionMode for CanonicalizeFreeRegionsOtherThanStatic { +impl CanonicalizeMode for CanonicalizeFreeRegionsOtherThanStatic { fn canonicalize_free_region<'tcx>( &self, canonicalizer: &mut Canonicalizer<'_, 'tcx>, @@ -257,6 +321,10 @@ impl CanonicalizeRegionMode for CanonicalizeFreeRegionsOtherThanStatic { fn any(&self) -> bool { true } + + fn preserve_universes(&self) -> bool { + false + } } struct Canonicalizer<'cx, 'tcx> { @@ -267,7 +335,7 @@ struct Canonicalizer<'cx, 'tcx> { // Note that indices is only used once `var_values` is big enough to be // heap-allocated. indices: FxHashMap, BoundVar>, - canonicalize_region_mode: &'cx dyn CanonicalizeRegionMode, + canonicalize_mode: &'cx dyn CanonicalizeMode, needs_canonical_flags: TypeFlags, binder_index: ty::DebruijnIndex, @@ -311,7 +379,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { vid, r ); let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid)); - self.canonicalize_region_mode.canonicalize_free_region(self, r) + self.canonicalize_mode.canonicalize_free_region(self, r) } ty::ReStatic @@ -319,7 +387,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { | ty::ReFree(_) | ty::ReEmpty(_) | ty::RePlaceholder(..) - | ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r), + | ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r), } } @@ -337,8 +405,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { // `TyVar(vid)` is unresolved, track its universe index in the canonicalized // result. Err(mut ui) => { - // FIXME: perf problem described in #55921. - ui = ty::UniverseIndex::ROOT; + if !self.canonicalize_mode.preserve_universes() { + // FIXME: perf problem described in #55921. + ui = ty::UniverseIndex::ROOT; + } self.canonicalize_ty_var( CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)), @@ -422,8 +492,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { // `ConstVar(vid)` is unresolved, track its universe index in the // canonicalized result Err(mut ui) => { - // FIXME: perf problem described in #55921. - ui = ty::UniverseIndex::ROOT; + if !self.canonicalize_mode.preserve_universes() { + // FIXME: perf problem described in #55921. + ui = ty::UniverseIndex::ROOT; + } return self.canonicalize_const_var( CanonicalVarInfo { kind: CanonicalVarKind::Const(ui, ct.ty) }, ct, @@ -462,7 +534,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { value: V, infcx: &InferCtxt<'_, 'tcx>, tcx: TyCtxt<'tcx>, - canonicalize_region_mode: &dyn CanonicalizeRegionMode, + canonicalize_region_mode: &dyn CanonicalizeMode, query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonicalized<'tcx, V> where @@ -493,7 +565,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { let mut canonicalizer = Canonicalizer { infcx, tcx, - canonicalize_region_mode, + canonicalize_mode: canonicalize_region_mode, needs_canonical_flags, variables: SmallVec::new(), query_state, @@ -504,10 +576,11 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { // Once we have canonicalized `out_value`, it should not // contain anything that ties it to this inference context - // anymore, so it should live in the global arena. - debug_assert!(!out_value.needs_infer()); + // anymore. + debug_assert!(!out_value.needs_infer() && !out_value.has_placeholders()); - let canonical_variables = tcx.intern_canonical_var_infos(&canonicalizer.variables); + let canonical_variables = + tcx.intern_canonical_var_infos(&canonicalizer.universe_canonicalized_variables()); let max_universe = canonical_variables .iter() @@ -527,6 +600,19 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { let var_values = &mut query_state.var_values; + let universe = info.universe(); + if universe != ty::UniverseIndex::ROOT { + assert!(self.canonicalize_mode.preserve_universes()); + + // Insert universe into the universe map. To preserve the order of the + // universes in the value being canonicalized, we don't update the + // universe in `info` until we have finished canonicalizing. + match query_state.universe_map.binary_search(&universe) { + Err(idx) => query_state.universe_map.insert(idx, universe), + Ok(_) => {} + } + } + // This code is hot. `variables` and `var_values` are usually small // (fewer than 8 elements ~95% of the time). They are SmallVec's to // avoid allocations in those cases. We also don't use `indices` to @@ -569,6 +655,61 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { } } + /// Replaces the universe indexes used in `var_values` with their index in + /// `query_state.universe_map`. This minimizes the maximum universe used in + /// the canonicalized value. + fn universe_canonicalized_variables(self) -> SmallVec<[CanonicalVarInfo<'tcx>; 8]> { + if self.query_state.universe_map.len() == 1 { + return self.variables; + } + + let reverse_universe_map: FxHashMap = self + .query_state + .universe_map + .iter() + .enumerate() + .map(|(idx, universe)| (*universe, ty::UniverseIndex::from_usize(idx))) + .collect(); + + self.variables + .iter() + .map(|v| CanonicalVarInfo { + kind: match v.kind { + CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => { + return *v; + } + CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => { + CanonicalVarKind::Ty(CanonicalTyVarKind::General(reverse_universe_map[&u])) + } + CanonicalVarKind::Region(u) => { + CanonicalVarKind::Region(reverse_universe_map[&u]) + } + CanonicalVarKind::Const(u, t) => { + CanonicalVarKind::Const(reverse_universe_map[&u], t) + } + CanonicalVarKind::PlaceholderTy(placeholder) => { + CanonicalVarKind::PlaceholderTy(ty::Placeholder { + universe: reverse_universe_map[&placeholder.universe], + ..placeholder + }) + } + CanonicalVarKind::PlaceholderRegion(placeholder) => { + CanonicalVarKind::PlaceholderRegion(ty::Placeholder { + universe: reverse_universe_map[&placeholder.universe], + ..placeholder + }) + } + CanonicalVarKind::PlaceholderConst(placeholder) => { + CanonicalVarKind::PlaceholderConst(ty::Placeholder { + universe: reverse_universe_map[&placeholder.universe], + ..placeholder + }) + } + }, + }) + .collect() + } + /// Shorthand helper that creates a canonical region variable for /// `r` (always in the root universe). The reason that we always /// put these variables into the root universe is because this diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 28217aeab13ee..4efe3640dfac6 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -64,9 +64,9 @@ pub struct CanonicalVarValues<'tcx> { /// result. #[derive(Clone, Debug)] pub struct OriginalQueryValues<'tcx> { - /// Map from the universes that appear in the query to the - /// universes in the caller context. For the time being, we only - /// ever put ROOT values into the query, so this map is very + /// Map from the universes that appear in the query to the universes in the + /// caller context. For all queries except `evaluate_goal` (used by Chalk), + /// we only ever put ROOT values into the query, so this map is very /// simple. pub universe_map: SmallVec<[ty::UniverseIndex; 4]>, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 4898a4844b9f7..e9aa4adcaf79b 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1457,9 +1457,9 @@ impl<'a> Parser<'a> { } else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() { self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs) } else if !ate_colon && (self.check(&TokenKind::Comma) || self.check(&TokenKind::Gt)) { - // We're probably inside of a `Path<'a>` that needs a turbofish, so suppress the - // "must be followed by a colon" error, and the "expected one of" error. - self.diagnostic().delay_span_bug(lo, "this label wasn't parsed correctly"); + // We're probably inside of a `Path<'a>` that needs a turbofish + let msg = "expected `while`, `for`, `loop` or `{` after a label"; + self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit(); consume_colon = false; Ok(self.mk_expr_err(lo)) } else { diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs index 34fc4ca8fead7..93c2f202545f6 100644 --- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs @@ -8,7 +8,7 @@ use crate::traits::{ PredicateObligation, SelectionError, TraitEngine, }; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, TypeFoldable}; pub struct FulfillmentContext<'tcx> { obligations: FxIndexSet>, @@ -91,7 +91,12 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { let environment = obligation.param_env.caller_bounds(); let goal = ChalkEnvironmentAndGoal { environment, goal: obligation.predicate }; let mut orig_values = OriginalQueryValues::default(); - let canonical_goal = infcx.canonicalize_query(goal, &mut orig_values); + if goal.references_error() { + continue; + } + + let canonical_goal = + infcx.canonicalize_query_preserving_universes(goal, &mut orig_values); match infcx.tcx.evaluate_goal(canonical_goal) { Ok(response) => { diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 3f51442277f59..0170ab223b031 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -20,11 +20,10 @@ use rustc_span::symbol::sym; use std::fmt; use std::sync::Arc; -use crate::chalk::lowering::{self, LowerInto}; +use crate::chalk::lowering::LowerInto; pub struct RustIrDatabase<'tcx> { pub(crate) interner: RustInterner<'tcx>, - pub(crate) reempty_placeholder: ty::Region<'tcx>, } impl fmt::Debug for RustIrDatabase<'_> { @@ -40,12 +39,9 @@ impl<'tcx> RustIrDatabase<'tcx> { bound_vars: SubstsRef<'tcx>, ) -> Vec>> { let predicates = self.interner.tcx.predicates_defined_on(def_id).predicates; - let mut regions_substitutor = - lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder); predicates .iter() .map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars)) - .map(|wc| wc.fold_with(&mut regions_substitutor)) .filter_map(|wc| LowerInto::< Option>> >::lower_into(wc, self.interner)).collect() @@ -287,9 +283,6 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let trait_ref = self.interner.tcx.impl_trait_ref(def_id).expect("not an impl"); let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars); - let mut regions_substitutor = - lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder); - let trait_ref = trait_ref.fold_with(&mut regions_substitutor); let where_clauses = self.where_clauses_for(def_id, bound_vars); @@ -335,9 +328,6 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let self_ty = trait_ref.self_ty(); let self_ty = self_ty.subst(self.interner.tcx, bound_vars); - let mut regions_substitutor = - lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder); - let self_ty = self_ty.fold_with(&mut regions_substitutor); let lowered_ty = self_ty.lower_into(self.interner); parameters[0].assert_ty_ref(self.interner).could_match( @@ -556,11 +546,11 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t Fn => lang_items.fn_trait(), FnMut => lang_items.fn_mut_trait(), FnOnce => lang_items.fn_once_trait(), + Generator => lang_items.gen_trait(), Unsize => lang_items.unsize_trait(), Unpin => lang_items.unpin_trait(), CoerceUnsized => lang_items.coerce_unsized_trait(), DiscriminantKind => lang_items.discriminant_kind_trait(), - Generator => lang_items.generator_return(), }; def_id.map(chalk_ir::TraitId) } @@ -684,28 +674,18 @@ impl<'tcx> chalk_ir::UnificationDatabase> for RustIrDatabase< let variances = self.interner.tcx.variances_of(def_id.0); chalk_ir::Variances::from_iter( self.interner, - variances.iter().map(|v| match v { - ty::Variance::Invariant => chalk_ir::Variance::Invariant, - ty::Variance::Covariant => chalk_ir::Variance::Covariant, - ty::Variance::Contravariant => chalk_ir::Variance::Contravariant, - ty::Variance::Bivariant => unimplemented!(), - }), + variances.iter().map(|v| v.lower_into(self.interner)), ) } fn adt_variance( &self, - def_id: chalk_ir::AdtId>, + adt_id: chalk_ir::AdtId>, ) -> chalk_ir::Variances> { - let variances = self.interner.tcx.variances_of(def_id.0.did); + let variances = self.interner.tcx.variances_of(adt_id.0.did); chalk_ir::Variances::from_iter( self.interner, - variances.iter().map(|v| match v { - ty::Variance::Invariant => chalk_ir::Variance::Invariant, - ty::Variance::Covariant => chalk_ir::Variance::Covariant, - ty::Variance::Contravariant => chalk_ir::Variance::Contravariant, - ty::Variance::Bivariant => unimplemented!(), - }), + variances.iter().map(|v| v.lower_into(self.interner)), ) } } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 67d0ba39667d3..6f143c1c607b3 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -188,12 +188,18 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi chalk_ir::DomainGoal::ObjectSafe(chalk_ir::TraitId(t)), ), + ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, a_is_expected: _ }) => { + chalk_ir::GoalData::SubtypeGoal(chalk_ir::SubtypeGoal { + a: a.lower_into(interner), + b: b.lower_into(interner), + }) + } + // FIXME(chalk): other predicates // // We can defer this, but ultimately we'll want to express // some of these in terms of chalk operations. ty::PredicateKind::ClosureKind(..) - | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) => { @@ -464,9 +470,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t }) .intern(interner) } - ReEmpty(_) => unimplemented!(), - // FIXME(chalk): need to handle ReErased - ReErased => unimplemented!(), + ReEmpty(ui) => { + chalk_ir::LifetimeData::Empty(chalk_ir::UniverseIndex { counter: ui.index() }) + .intern(interner) + } + ReErased => chalk_ir::LifetimeData::Erased.intern(interner), } } } @@ -488,12 +496,12 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime ty::RegionKind::ReStatic, - chalk_ir::LifetimeData::Phantom(_, _) => unimplemented!(), + chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static, chalk_ir::LifetimeData::Empty(ui) => { - ty::RegionKind::ReEmpty(ty::UniverseIndex::from_usize(ui.counter)) + ty::ReEmpty(ty::UniverseIndex::from_usize(ui.counter)) } - chalk_ir::LifetimeData::Erased => ty::RegionKind::ReErased, + chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased, + chalk_ir::LifetimeData::Phantom(void, _) => match *void {}, }; interner.tcx.mk_region(kind) } @@ -788,6 +796,16 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::Polarity> for ty::ImplPolarity } } } +impl<'tcx> LowerInto<'tcx, chalk_ir::Variance> for ty::Variance { + fn lower_into(self, _interner: RustInterner<'tcx>) -> chalk_ir::Variance { + match self { + ty::Variance::Covariant => chalk_ir::Variance::Covariant, + ty::Variance::Invariant => chalk_ir::Variance::Invariant, + ty::Variance::Contravariant => chalk_ir::Variance::Contravariant, + ty::Variance::Bivariant => unimplemented!(), + } + } +} impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound>> for ty::ProjectionPredicate<'tcx> @@ -1016,10 +1034,6 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match *t.kind() { - // FIXME(chalk): currently we convert params to placeholders starting at - // index `0`. To support placeholders, we'll actually need to do a - // first pass to collect placeholders. Then we can insert params after. - ty::Placeholder(_) => unimplemented!(), ty::Param(param) => match self.list.iter().position(|r| r == ¶m) { Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::from_usize(0), @@ -1035,15 +1049,15 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { })) } }, - _ => t.super_fold_with(self), } } fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { match r { - // FIXME(chalk) - jackh726 - this currently isn't hit in any tests. - // This covers any region variables in a goal, right? + // FIXME(chalk) - jackh726 - this currently isn't hit in any tests, + // since canonicalization will already change these to canonical + // variables (ty::ReLateBound). ty::ReEarlyBound(_re) => match self.named_regions.get(&_re.def_id) { Some(idx) => { let br = ty::BoundRegion { @@ -1066,6 +1080,39 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { } } +crate struct ReverseParamsSubstitutor<'tcx> { + tcx: TyCtxt<'tcx>, + params: rustc_data_structures::fx::FxHashMap, +} + +impl<'tcx> ReverseParamsSubstitutor<'tcx> { + crate fn new( + tcx: TyCtxt<'tcx>, + params: rustc_data_structures::fx::FxHashMap, + ) -> Self { + Self { tcx, params } + } +} + +impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + match *t.kind() { + ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, name }) => { + match self.params.get(&name.as_usize()) { + Some(param) => self.tcx.mk_ty(ty::Param(*param)), + None => t, + } + } + + _ => t.super_fold_with(self), + } + } +} + /// Used to collect `Placeholder`s. crate struct PlaceholdersCollector { universe_index: ty::UniverseIndex, @@ -1110,32 +1157,3 @@ impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { r.super_visit_with(self) } } - -/// Used to substitute specific `Regions`s with placeholders. -crate struct RegionsSubstitutor<'tcx> { - tcx: TyCtxt<'tcx>, - reempty_placeholder: ty::Region<'tcx>, -} - -impl<'tcx> RegionsSubstitutor<'tcx> { - crate fn new(tcx: TyCtxt<'tcx>, reempty_placeholder: ty::Region<'tcx>) -> Self { - RegionsSubstitutor { tcx, reempty_placeholder } - } -} - -impl<'tcx> TypeFolder<'tcx> for RegionsSubstitutor<'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { - match r { - ty::ReEmpty(ui) => { - assert_eq!(ui.as_usize(), 0); - self.reempty_placeholder - } - - _ => r.super_fold_with(self), - } - } -} diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index 09bfdabf47373..3c2a266dab9bc 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -22,9 +22,8 @@ use rustc_infer::infer::canonical::{ use rustc_infer::traits::{self, CanonicalChalkEnvironmentAndGoal}; use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase; -use crate::chalk::lowering::{ - LowerInto, ParamsSubstitutor, PlaceholdersCollector, RegionsSubstitutor, -}; +use crate::chalk::lowering::LowerInto; +use crate::chalk::lowering::{ParamsSubstitutor, PlaceholdersCollector, ReverseParamsSubstitutor}; use chalk_solve::Solution; @@ -42,19 +41,10 @@ crate fn evaluate_goal<'tcx>( let mut placeholders_collector = PlaceholdersCollector::new(); obligation.visit_with(&mut placeholders_collector); - let reempty_placeholder = tcx.mk_region(ty::RegionKind::RePlaceholder(ty::Placeholder { - universe: ty::UniverseIndex::ROOT, - name: ty::BoundRegionKind::BrAnon(placeholders_collector.next_anon_region_placeholder + 1), - })); - let mut params_substitutor = ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder); let obligation = obligation.fold_with(&mut params_substitutor); - // FIXME(chalk): we really should be substituting these back in the solution - let _params: FxHashMap = params_substitutor.params; - - let mut regions_substitutor = RegionsSubstitutor::new(tcx, reempty_placeholder); - let obligation = obligation.fold_with(&mut regions_substitutor); + let params: FxHashMap = params_substitutor.params; let max_universe = obligation.max_universe.index(); @@ -96,7 +86,8 @@ crate fn evaluate_goal<'tcx>( use chalk_solve::Solver; let mut solver = chalk_engine::solve::SLGSolver::new(32, None); - let db = ChalkRustIrDatabase { interner, reempty_placeholder }; + let db = ChalkRustIrDatabase { interner }; + debug!(?lowered_goal); let solution = solver.solve(&db, &lowered_goal); debug!(?obligation, ?solution, "evaluate goal"); @@ -110,8 +101,9 @@ crate fn evaluate_goal<'tcx>( use rustc_middle::infer::canonical::CanonicalVarInfo; let mut var_values: IndexVec> = IndexVec::new(); + let mut reverse_param_substitutor = ReverseParamsSubstitutor::new(tcx, params); subst.as_slice(interner).iter().for_each(|p| { - var_values.push(p.lower_into(interner)); + var_values.push(p.lower_into(interner).fold_with(&mut reverse_param_substitutor)); }); let variables: Vec<_> = binders .iter(interner) diff --git a/src/test/pretty/use-tree.rs b/src/test/pretty/use-tree.rs new file mode 100644 index 0000000000000..5da9523524552 --- /dev/null +++ b/src/test/pretty/use-tree.rs @@ -0,0 +1,23 @@ +// pp-exact +// edition:2021 + +#![allow(unused_imports)] + +use ::std::fmt::{self, Debug, Display, Write as _}; + +use core::option::Option::*; + +use core::{ + cmp::{Eq, Ord, PartialEq, PartialOrd}, + convert::{AsMut, AsRef, From, Into}, + iter::{ + DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, + IntoIterator, Iterator, + }, + marker::{ + Copy as Copy, Send as Send, Sized as Sized, Sync as Sync, Unpin as U, + }, + ops::{*, Drop, Fn, FnMut, FnOnce}, +}; + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs index 0c4907fd00294..d180de9be3bf3 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs @@ -1,6 +1,5 @@ // NOTE: rustc cannot currently handle bounds of the form `for<'a> >::Assoc: Baz`. // This should hopefully be fixed with Chalk. -// ignore-compare-mode-chalk #![feature(associated_type_bounds)] diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index 4ecae471ec2da..c23e54594ee30 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -1,5 +1,5 @@ error[E0277]: `<::C as Iterator>::Item` cannot be sent between threads safely - --> $DIR/bad-bounds-on-assoc-in-trait.rs:27:36 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:36 | LL | type C: Clone + Iterator Lam<&'a u8, App: Debug>> + Sync>; | ^^^^ `<::C as Iterator>::Item` cannot be sent between threads safely @@ -11,7 +11,7 @@ LL | trait Case1 where <::C as Iterator>::Item: Send { | ++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0277]: `<::C as Iterator>::Item` is not an iterator - --> $DIR/bad-bounds-on-assoc-in-trait.rs:27:43 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:43 | LL | type C: Clone + Iterator Lam<&'a u8, App: Debug>> + Sync>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<::C as Iterator>::Item` is not an iterator @@ -23,7 +23,7 @@ LL | trait Case1 where <::C as Iterator>::Item: Iterator { | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0277]: `<::C as Iterator>::Item` cannot be shared between threads safely - --> $DIR/bad-bounds-on-assoc-in-trait.rs:27:93 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:93 | LL | type C: Clone + Iterator Lam<&'a u8, App: Debug>> + Sync>; | ^^^^ `<::C as Iterator>::Item` cannot be shared between threads safely diff --git a/src/test/ui/associated-type-bounds/trait-params.rs b/src/test/ui/associated-type-bounds/trait-params.rs index a9aa2747e52af..b0703a4ee22b3 100644 --- a/src/test/ui/associated-type-bounds/trait-params.rs +++ b/src/test/ui/associated-type-bounds/trait-params.rs @@ -1,5 +1,4 @@ // build-pass (FIXME(62277): could be check-pass?) -// ignore-compare-mode-chalk #![feature(associated_type_bounds)] diff --git a/src/test/ui/associated-type-bounds/union-bounds.rs b/src/test/ui/associated-type-bounds/union-bounds.rs index f1aab2a6da071..97c5acf1f72ca 100644 --- a/src/test/ui/associated-type-bounds/union-bounds.rs +++ b/src/test/ui/associated-type-bounds/union-bounds.rs @@ -1,5 +1,4 @@ // run-pass -// ignore-compare-mode-chalk #![feature(associated_type_bounds)] #![feature(untagged_unions)] diff --git a/src/test/ui/associated-types/associated-types-stream.rs b/src/test/ui/associated-types/associated-types-stream.rs index 220ee6af2fc9f..c9b302b96919f 100644 --- a/src/test/ui/associated-types/associated-types-stream.rs +++ b/src/test/ui/associated-types/associated-types-stream.rs @@ -1,8 +1,6 @@ // run-pass // Test references to the trait `Stream` in the bounds for associated // types defined on `Stream`. Issue #20551. -// ignore-compare-mode-chalk - trait Stream { type Car; diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-2.rs b/src/test/ui/associated-types/hr-associated-type-bound-param-2.rs index 5193400882d12..f74c5a8590d1d 100644 --- a/src/test/ui/associated-types/hr-associated-type-bound-param-2.rs +++ b/src/test/ui/associated-types/hr-associated-type-bound-param-2.rs @@ -1,4 +1,3 @@ -// ignore-compare-mode-chalk trait Z<'a, T: ?Sized> where T: Z<'a, u16>, diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr b/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr index 730229b5208da..354caef1e41d8 100644 --- a/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr +++ b/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-2.rs:4:8 + --> $DIR/hr-associated-type-bound-param-2.rs:3:8 | LL | T: Z<'a, u16>, | ^^^^^^^^^^ the trait `Clone` is not implemented for `str` | note: required by a bound in `Z` - --> $DIR/hr-associated-type-bound-param-2.rs:7:35 + --> $DIR/hr-associated-type-bound-param-2.rs:6:35 | LL | trait Z<'a, T: ?Sized> | - required by a bound in this @@ -14,13 +14,13 @@ LL | for<'b> >::W: Clone, | ^^^^^ required by this bound in `Z` error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-2.rs:4:8 + --> $DIR/hr-associated-type-bound-param-2.rs:3:8 | LL | T: Z<'a, u16>, | ^^^^^^^^^^ the trait `Clone` is not implemented for `str` | note: required by a bound in `Z` - --> $DIR/hr-associated-type-bound-param-2.rs:7:35 + --> $DIR/hr-associated-type-bound-param-2.rs:6:35 | LL | trait Z<'a, T: ?Sized> | - required by a bound in this @@ -29,13 +29,13 @@ LL | for<'b> >::W: Clone, | ^^^^^ required by this bound in `Z` error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-2.rs:16:14 + --> $DIR/hr-associated-type-bound-param-2.rs:15:14 | LL | type W = str; | ^^^ the trait `Clone` is not implemented for `str` | note: required by a bound in `Z` - --> $DIR/hr-associated-type-bound-param-2.rs:7:35 + --> $DIR/hr-associated-type-bound-param-2.rs:6:35 | LL | trait Z<'a, T: ?Sized> | - required by a bound in this diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-5.rs b/src/test/ui/associated-types/hr-associated-type-bound-param-5.rs index 920aa83528070..d7f3151a502ee 100644 --- a/src/test/ui/associated-types/hr-associated-type-bound-param-5.rs +++ b/src/test/ui/associated-types/hr-associated-type-bound-param-5.rs @@ -1,4 +1,3 @@ -// ignore-compare-mode-chalk trait Cycle: Sized { type Next: Cycle; } diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-5.stderr b/src/test/ui/associated-types/hr-associated-type-bound-param-5.stderr index 63cd89316b38c..4c04d12a71470 100644 --- a/src/test/ui/associated-types/hr-associated-type-bound-param-5.stderr +++ b/src/test/ui/associated-types/hr-associated-type-bound-param-5.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-5.rs:27:14 + --> $DIR/hr-associated-type-bound-param-5.rs:26:14 | LL | type U = str; | ^^^ the trait `Clone` is not implemented for `str` | note: required by a bound in `X` - --> $DIR/hr-associated-type-bound-param-5.rs:18:45 + --> $DIR/hr-associated-type-bound-param-5.rs:17:45 | LL | trait X<'a, T: Cycle + for<'b> X<'b, T>> | - required by a bound in this @@ -14,13 +14,13 @@ LL | for<'b> >::U: Clone, | ^^^^^ required by this bound in `X` error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-5.rs:32:14 + --> $DIR/hr-associated-type-bound-param-5.rs:31:14 | LL | type U = str; | ^^^ the trait `Clone` is not implemented for `str` | note: required by a bound in `X` - --> $DIR/hr-associated-type-bound-param-5.rs:18:45 + --> $DIR/hr-associated-type-bound-param-5.rs:17:45 | LL | trait X<'a, T: Cycle + for<'b> X<'b, T>> | - required by a bound in this diff --git a/src/test/ui/associated-types/issue-50301.rs b/src/test/ui/associated-types/issue-50301.rs index 4fcb41485d0e2..47ee3e7ad70e8 100644 --- a/src/test/ui/associated-types/issue-50301.rs +++ b/src/test/ui/associated-types/issue-50301.rs @@ -1,6 +1,5 @@ // Tests that HRTBs are correctly accepted -- https://github.com/rust-lang/rust/issues/50301 // check-pass -// ignore-compare-mode-chalk trait Trait where for<'a> &'a Self::IntoIter: IntoIterator, diff --git a/src/test/ui/associated-types/issue-91069.rs b/src/test/ui/associated-types/issue-91069.rs new file mode 100644 index 0000000000000..109c2eed27a33 --- /dev/null +++ b/src/test/ui/associated-types/issue-91069.rs @@ -0,0 +1,24 @@ +// check-pass + +pub trait Associate { + type Associated; +} + +pub struct Wrap<'a> { + pub field: &'a i32, +} + +pub trait Create { + fn create() -> Self; +} + +pub fn oh_no<'a, T>() +where + Wrap<'a>: Associate, + as Associate>::Associated: Create, +{ + as Associate>::Associated::create(); +} + + +pub fn main() {} diff --git a/src/test/ui/chalkify/assert.rs b/src/test/ui/chalkify/assert.rs new file mode 100644 index 0000000000000..f4ebf91924ced --- /dev/null +++ b/src/test/ui/chalkify/assert.rs @@ -0,0 +1,6 @@ +// run-pass +// compile-flags: -Z chalk + +fn main() { + assert_eq!(1, 1); +} diff --git a/src/test/ui/chalkify/println.rs b/src/test/ui/chalkify/println.rs index cf36aef8afaf3..0f0df29019e7b 100644 --- a/src/test/ui/chalkify/println.rs +++ b/src/test/ui/chalkify/println.rs @@ -2,6 +2,5 @@ // compile-flags: -Z chalk fn main() { - // FIXME(chalk): Require `RegionOutlives`/`TypeOutlives`/`Subtype` support - //println!("hello"); + println!("hello"); } diff --git a/src/test/ui/chalkify/trait-objects.rs b/src/test/ui/chalkify/trait-objects.rs index 13d9e6a657885..d56abc42bf540 100644 --- a/src/test/ui/chalkify/trait-objects.rs +++ b/src/test/ui/chalkify/trait-objects.rs @@ -5,8 +5,7 @@ use std::fmt::Display; fn main() { let d: &dyn Display = &mut 3; - // FIXME(chalk) should be able to call d.to_string() as well, but doing so - // requires Chalk to be able to prove trait object well-formed goals. + d.to_string(); (&d).to_string(); let f: &dyn Fn(i32) -> _ = &|x| x + x; f(2); diff --git a/src/test/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr new file mode 100644 index 0000000000000..2a4b6f3b76f90 --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr @@ -0,0 +1,9 @@ +error[E0284]: type annotations needed: cannot satisfy `>::Output == _` + --> $DIR/ub-nonnull.rs:19:30 + | +LL | let out_of_bounds_ptr = &ptr[255]; + | ^^^^^^^^ cannot satisfy `>::Output == _` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr new file mode 100644 index 0000000000000..39352ca848a80 --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/ub-wide-ptr.rs:90:67 + | +LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); + | ^^^^^^^^^^^^^^ cannot infer type for type parameter `U` declared on the function `transmute` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/deriving/deriving-associated-types.rs b/src/test/ui/deriving/deriving-associated-types.rs index 13735ff2c5a1c..4b1cbe80c506d 100644 --- a/src/test/ui/deriving/deriving-associated-types.rs +++ b/src/test/ui/deriving/deriving-associated-types.rs @@ -1,5 +1,4 @@ // run-pass -// ignore-compare-mode-chalk pub trait DeclaredTrait { type Type; } diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.rs b/src/test/ui/generic-associated-types/bugs/issue-80626.rs new file mode 100644 index 0000000000000..aea8aaf4bb393 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-80626.rs @@ -0,0 +1,17 @@ +// check-fail + +// This should pass, but it requires `Sized` to be coinductive. + +#![feature(generic_associated_types)] + +trait Allocator { + type Allocated; +} + +enum LinkedList { + Head, + Next(A::Allocated) + //~^ overflow +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr new file mode 100644 index 0000000000000..e18af9c257f7f --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr @@ -0,0 +1,20 @@ +error[E0275]: overflow evaluating the requirement `LinkedList: Sized` + --> $DIR/issue-80626.rs:13:10 + | +LL | Next(A::Allocated) + | ^^^^^^^^^^^^^^^^^^ + | + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | Next(&A::Allocated) + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | Next(Box>) + | ++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.rs b/src/test/ui/generic-associated-types/bugs/issue-86218.rs new file mode 100644 index 0000000000000..3f8776a363770 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-86218.rs @@ -0,0 +1,27 @@ +// check-fail + +// This should pass, but seems to run into a TAIT issue. + +#![feature(generic_associated_types)] +#![feature(type_alias_impl_trait)] + +pub trait Stream { + type Item; +} + +impl Stream for () { + type Item = i32; +} + +trait Yay { + type InnerStream<'s>: Stream + 's; + fn foo<'s>() -> Self::InnerStream<'s>; +} + +impl<'a> Yay<&'a ()> for () { + type InnerStream<'s> = impl Stream + 's; + //~^ the type + fn foo<'s>() -> Self::InnerStream<'s> { todo!() } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.stderr b/src/test/ui/generic-associated-types/bugs/issue-86218.stderr new file mode 100644 index 0000000000000..9f4efc0addb73 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-86218.stderr @@ -0,0 +1,15 @@ +error[E0477]: the type `impl Stream` does not fulfill the required lifetime + --> $DIR/issue-86218.rs:22:28 + | +LL | type InnerStream<'s> = impl Stream + 's; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: type must outlive the lifetime `'s` as defined here as required by this binding + --> $DIR/issue-86218.rs:22:22 + | +LL | type InnerStream<'s> = impl Stream + 's; + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0477`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-87735.rs b/src/test/ui/generic-associated-types/bugs/issue-87735.rs new file mode 100644 index 0000000000000..5f7a42a740df6 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87735.rs @@ -0,0 +1,45 @@ +// check-fail + +// This should pass, but we need an extension of implied bounds (probably). + +#![feature(generic_associated_types)] + +pub trait AsRef2 { + type Output<'a> where Self: 'a; + + fn as_ref2<'a>(&'a self) -> Self::Output<'a>; +} + +impl AsRef2 for Vec { + type Output<'a> where Self: 'a = &'a [T]; + + fn as_ref2<'a>(&'a self) -> Self::Output<'a> { + &self[..] + } +} + +#[derive(Debug)] +struct Foo(T); +#[derive(Debug)] +struct FooRef<'a, U>(&'a [U]); + +impl<'b, T, U> AsRef2 for Foo //~ the type parameter +where + // * `for<'b, 'c> T: AsRef2 = &'c [U]>>` does not work + // + // * `U` is unconstrained but should be allowed in this context because `Output` is + // an associated type + T: AsRef2 = &'b [U]>, + U: 'b +{ + type Output<'a> where Self: 'a = FooRef<'a, U>; + + fn as_ref2<'a>(&'a self) -> Self::Output<'a> { + FooRef(self.0.as_ref2()) + } +} + +fn main() { + let foo = Foo(vec![1, 2, 3]); + dbg!(foo.as_ref2()); +} diff --git a/src/test/ui/generic-associated-types/bugs/issue-87735.stderr b/src/test/ui/generic-associated-types/bugs/issue-87735.stderr new file mode 100644 index 0000000000000..31b3a9619b6af --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87735.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-87735.rs:26:13 + | +LL | impl<'b, T, U> AsRef2 for Foo + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-87748.rs b/src/test/ui/generic-associated-types/bugs/issue-87748.rs new file mode 100644 index 0000000000000..4dbaf429ead26 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87748.rs @@ -0,0 +1,22 @@ +// check-fail + +// This should pass, but unnormalized input args aren't treated as implied. + +#![feature(generic_associated_types)] + +trait MyTrait { + type Assoc<'a, 'b> where 'b: 'a; + fn do_sth(arg: Self::Assoc<'_, '_>); +} + +struct Foo; + +impl MyTrait for Foo { + type Assoc<'a, 'b> where 'b: 'a = u32; + + fn do_sth(_: u32) {} //~ lifetime bound + // fn do_sth(_: Self::Assoc<'static, 'static>) {} + // fn do_sth(_: Self::Assoc<'_, '_>) {} +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-87748.stderr b/src/test/ui/generic-associated-types/bugs/issue-87748.stderr new file mode 100644 index 0000000000000..c38d447859233 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87748.stderr @@ -0,0 +1,20 @@ +error[E0478]: lifetime bound not satisfied + --> $DIR/issue-87748.rs:17:5 + | +LL | fn do_sth(_: u32) {} + | ^^^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the anonymous lifetime #2 defined here + --> $DIR/issue-87748.rs:17:5 + | +LL | fn do_sth(_: u32) {} + | ^^^^^^^^^^^^^^^^^ +note: but lifetime parameter must outlive the anonymous lifetime #1 defined here + --> $DIR/issue-87748.rs:17:5 + | +LL | fn do_sth(_: u32) {} + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0478`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.rs b/src/test/ui/generic-associated-types/bugs/issue-87755.rs new file mode 100644 index 0000000000000..1cd3534ba77a0 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87755.rs @@ -0,0 +1,21 @@ +// check-fail + +// This should pass. + +#![feature(generic_associated_types)] + +use std::fmt::Debug; + +trait Foo { + type Ass where Self::Ass: Debug; +} + +#[derive(Debug)] +struct Bar; + +impl Foo for Bar { + type Ass = Bar; + //~^ overflow +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.stderr b/src/test/ui/generic-associated-types/bugs/issue-87755.stderr new file mode 100644 index 0000000000000..d2dc991a2b640 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87755.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Ass == _` + --> $DIR/issue-87755.rs:17:16 + | +LL | type Ass = Bar; + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.rs b/src/test/ui/generic-associated-types/bugs/issue-87803.rs new file mode 100644 index 0000000000000..3d2ff38ab049e --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87803.rs @@ -0,0 +1,26 @@ +// check-fail + +// This should pass, but using a type alias vs a reference directly +// changes late-bound -> early-bound. + +#![feature(generic_associated_types)] + +trait Scanner { + type Input<'a>; + type Token<'a>; + + fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>; +} + +struct IdScanner(); + +impl Scanner for IdScanner { + type Input<'a> = &'a str; + type Token<'a> = &'a str; + + fn scan<'a>(&mut self, s : &'a str) -> &'a str { //~ lifetime parameters + s + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.stderr b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr new file mode 100644 index 0000000000000..759c0440d07ba --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr @@ -0,0 +1,12 @@ +error[E0195]: lifetime parameters or bounds on method `scan` do not match the trait declaration + --> $DIR/issue-87803.rs:21:12 + | +LL | fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>; + | ---- lifetimes in impl do not match this method in trait +... +LL | fn scan<'a>(&mut self, s : &'a str) -> &'a str { + | ^^^^ lifetimes do not match method in trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0195`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.rs b/src/test/ui/generic-associated-types/bugs/issue-88382.rs new file mode 100644 index 0000000000000..f4633ca516999 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88382.rs @@ -0,0 +1,31 @@ +// check-fail + +// This should pass, but has a missed normalization due to HRTB. + +#![feature(generic_associated_types)] + +trait Iterable { + type Iterator<'a> where Self: 'a; + fn iter(&self) -> Self::Iterator<'_>; +} + +struct SomeImplementation(); + +impl Iterable for SomeImplementation { + type Iterator<'a> = std::iter::Empty; + fn iter(&self) -> Self::Iterator<'_> { + std::iter::empty() + } +} + +fn do_something(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) { + f(&mut i.iter()); +} + +fn main() { + do_something(SomeImplementation(), |_| ()); + do_something(SomeImplementation(), test); + //~^ type mismatch +} + +fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.stderr b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr new file mode 100644 index 0000000000000..05bc58cbba4e6 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr @@ -0,0 +1,20 @@ +error[E0631]: type mismatch in function arguments + --> $DIR/issue-88382.rs:27:40 + | +LL | do_something(SomeImplementation(), test); + | ------------ ^^^^ expected signature of `for<'a> fn(&mut ::Iterator<'a>) -> _` + | | + | required by a bound introduced by this call +... +LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {} + | ------------------------------------------------- found signature of `for<'r> fn(&'r mut std::iter::Empty) -> _` + | +note: required by a bound in `do_something` + --> $DIR/issue-88382.rs:21:56 + | +LL | fn do_something(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.rs b/src/test/ui/generic-associated-types/bugs/issue-88460.rs new file mode 100644 index 0000000000000..7e62790cc50c3 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88460.rs @@ -0,0 +1,31 @@ +// check-fail + +// This should pass, but has a missed normalization due to HRTB. + +#![feature(generic_associated_types)] + +pub trait Marker {} + +pub trait Trait { + type Assoc<'a>; +} + +fn test(value: T) +where + T: Trait, + for<'a> T::Assoc<'a>: Marker, +{ +} + +impl Marker for () {} + +struct Foo; + +impl Trait for Foo { + type Assoc<'a> = (); +} + +fn main() { + test(Foo); + //~^ the trait bound +} diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.stderr b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr new file mode 100644 index 0000000000000..604658da7d2c2 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied + --> $DIR/issue-88460.rs:29:5 + | +LL | test(Foo); + | ^^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>` + | +note: required by a bound in `test` + --> $DIR/issue-88460.rs:16:27 + | +LL | fn test(value: T) + | ---- required by a bound in this +... +LL | for<'a> T::Assoc<'a>: Marker, + | ^^^^^^ required by this bound in `test` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-88526.rs b/src/test/ui/generic-associated-types/bugs/issue-88526.rs new file mode 100644 index 0000000000000..90568fcb40125 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88526.rs @@ -0,0 +1,34 @@ +// check-fail + +// This should pass, but requires more logic. + +#![feature(generic_associated_types)] + +trait A { + type I<'a>; +} + +pub struct TestA +{ + f: F, +} + +impl A for TestA { + type I<'a> = &'a F; +} + +struct TestB +{ + q: Q, + f: F, +} + +impl<'q, Q, I, F> A for TestB //~ the type parameter +where + Q: A = &'q I>, + F: Fn(I), +{ + type I<'a> = (); +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-88526.stderr b/src/test/ui/generic-associated-types/bugs/issue-88526.stderr new file mode 100644 index 0000000000000..ccc5ae0b621a1 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88526.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `I` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-88526.rs:26:13 + | +LL | impl<'q, Q, I, F> A for TestB + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.rs b/src/test/ui/generic-associated-types/bugs/issue-89008.rs new file mode 100644 index 0000000000000..5d850849fd21c --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-89008.rs @@ -0,0 +1,43 @@ +// check-fail +// edition:2021 + +// This should pass, but seems to run into a TAIT bug. + +#![feature(type_alias_impl_trait)] +#![feature(generic_associated_types)] + +use std::future::Future; + +trait Stream { + type Item; +} + +struct Empty(T); +impl Stream for Empty { + type Item = (); +} +fn empty() -> Empty { + todo!() +} + +trait X { + type LineStream<'a, Repr>: Stream where Self: 'a; + + type LineStreamFut<'a,Repr>: Future> where Self: 'a; + + fn line_stream<'a,Repr>(&'a self) -> Self::LineStreamFut<'a,Repr>; +} + +struct Y; + +impl X for Y { + type LineStream<'a, Repr> = impl Stream; //~ could not find + + type LineStreamFut<'a, Repr> = impl Future> ; + + fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> { //~ type mismatch + async {empty()} + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.stderr b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr new file mode 100644 index 0000000000000..48745fe0fbd96 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr @@ -0,0 +1,21 @@ +error[E0271]: type mismatch resolving ` as Future>::Output == impl Stream` + --> $DIR/issue-89008.rs:38:43 + | +LL | type LineStream<'a, Repr> = impl Stream; + | ------------------------ the expected opaque type +... +LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found struct `Empty` + | + = note: expected opaque type `impl Stream` + found struct `Empty<_>` + +error: could not find defining uses + --> $DIR/issue-89008.rs:34:33 + | +LL | type LineStream<'a, Repr> = impl Stream; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/generic-associated-types/issue-91139.rs b/src/test/ui/generic-associated-types/issue-91139.rs new file mode 100644 index 0000000000000..2b82d2946b3ba --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-91139.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(generic_associated_types)] + +trait Foo { + type Type<'a> + where + T: 'a; +} + +impl Foo for () { + type Type<'a> + where + T: 'a, + = (); +} + +fn foo() { + let _: for<'a> fn(<() as Foo>::Type<'a>, &'a T) = |_, _| (); +} + +pub fn main() {} diff --git a/src/test/ui/impl-trait/example-calendar.rs b/src/test/ui/impl-trait/example-calendar.rs index 45dcb74a6e05c..da45f0d133deb 100644 --- a/src/test/ui/impl-trait/example-calendar.rs +++ b/src/test/ui/impl-trait/example-calendar.rs @@ -1,5 +1,4 @@ // run-pass -// ignore-compare-mode-chalk #![feature(fn_traits, step_trait, diff --git a/src/test/ui/impl-trait/issue-55872-2.rs b/src/test/ui/impl-trait/issue-55872-2.rs index a519397806e07..17a6a85787442 100644 --- a/src/test/ui/impl-trait/issue-55872-2.rs +++ b/src/test/ui/impl-trait/issue-55872-2.rs @@ -1,5 +1,4 @@ // edition:2018 -// ignore-compare-mode-chalk #![feature(type_alias_impl_trait)] diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr index 97545ba3d1124..b76b564dfb139 100644 --- a/src/test/ui/impl-trait/issue-55872-2.stderr +++ b/src/test/ui/impl-trait/issue-55872-2.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `impl Future: Copy` is not satisfied - --> $DIR/issue-55872-2.rs:14:20 + --> $DIR/issue-55872-2.rs:13:20 | LL | fn foo() -> Self::E { | ^^^^^^^ the trait `Copy` is not implemented for `impl Future` error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-2.rs:14:28 + --> $DIR/issue-55872-2.rs:13:28 | LL | fn foo() -> Self::E { | ____________________________^ diff --git a/src/test/ui/impl-trait/issue-55872.rs b/src/test/ui/impl-trait/issue-55872.rs index bbd940254178c..183728b0f7f0a 100644 --- a/src/test/ui/impl-trait/issue-55872.rs +++ b/src/test/ui/impl-trait/issue-55872.rs @@ -1,4 +1,3 @@ -// ignore-compare-mode-chalk #![feature(type_alias_impl_trait)] pub trait Bar { diff --git a/src/test/ui/impl-trait/issue-55872.stderr b/src/test/ui/impl-trait/issue-55872.stderr index 60654ec34610f..39d870dc003bb 100644 --- a/src/test/ui/impl-trait/issue-55872.stderr +++ b/src/test/ui/impl-trait/issue-55872.stderr @@ -1,5 +1,5 @@ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872.rs:13:28 + --> $DIR/issue-55872.rs:12:28 | LL | fn foo() -> Self::E { | ____________________________^ diff --git a/src/test/ui/impl-trait/issues/issue-65581.rs b/src/test/ui/impl-trait/issues/issue-65581.rs index af65b79d3e838..b947fc1d2396f 100644 --- a/src/test/ui/impl-trait/issues/issue-65581.rs +++ b/src/test/ui/impl-trait/issues/issue-65581.rs @@ -1,4 +1,5 @@ // check-pass +// ignore-compare-mode-chalk #![allow(dead_code)] diff --git a/src/test/ui/issues/issue-23122-1.rs b/src/test/ui/issues/issue-23122-1.rs index efa4e614be5b0..7fe0900ed5fde 100644 --- a/src/test/ui/issues/issue-23122-1.rs +++ b/src/test/ui/issues/issue-23122-1.rs @@ -1,10 +1,10 @@ -// ignore-compare-mode-chalk - trait Next { type Next: Next; } -struct GetNext { t: T } +struct GetNext { + t: T, +} impl Next for GetNext { type Next = as Next>::Next; diff --git a/src/test/ui/issues/issue-23122-2.rs b/src/test/ui/issues/issue-23122-2.rs index 7866b931ec4b9..95e1f60d8b029 100644 --- a/src/test/ui/issues/issue-23122-2.rs +++ b/src/test/ui/issues/issue-23122-2.rs @@ -1,9 +1,10 @@ -// ignore-compare-mode-chalk trait Next { type Next: Next; } -struct GetNext { t: T } +struct GetNext { + t: T, +} impl Next for GetNext { type Next = as Next>::Next; diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr index b345e90178742..7519e632d5446 100644 --- a/src/test/ui/issues/issue-23122-2.stderr +++ b/src/test/ui/issues/issue-23122-2.stderr @@ -1,12 +1,12 @@ error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized` - --> $DIR/issue-23122-2.rs:9:17 + --> $DIR/issue-23122-2.rs:10:17 | LL | type Next = as Next>::Next; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`) note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` - --> $DIR/issue-23122-2.rs:8:15 + --> $DIR/issue-23122-2.rs:9:15 | LL | impl Next for GetNext { | ^^^^ ^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-28561.rs b/src/test/ui/issues/issue-28561.rs index 184f5cb26c546..1241fb0b1f85f 100644 --- a/src/test/ui/issues/issue-28561.rs +++ b/src/test/ui/issues/issue-28561.rs @@ -1,5 +1,4 @@ // check-pass -// ignore-compare-mode-chalk #[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] struct Array { f00: [T; 00], diff --git a/src/test/ui/issues/issue-33187.rs b/src/test/ui/issues/issue-33187.rs index f6b56610ec7d9..8db9e00588564 100644 --- a/src/test/ui/issues/issue-33187.rs +++ b/src/test/ui/issues/issue-33187.rs @@ -1,10 +1,15 @@ // run-pass -// ignore-compare-mode-chalk + struct Foo(::Data); -impl Copy for Foo where ::Data: Copy { } -impl Clone for Foo where ::Data: Clone { - fn clone(&self) -> Self { Foo(self.0.clone()) } +impl Copy for Foo where ::Data: Copy {} +impl Clone for Foo +where + ::Data: Clone, +{ + fn clone(&self) -> Self { + Foo(self.0.clone()) + } } trait Repr { @@ -15,5 +20,4 @@ impl Repr for A { type Data = u32; } -fn main() { -} +fn main() {} diff --git a/src/test/ui/issues/issue-37051.rs b/src/test/ui/issues/issue-37051.rs index e0c47197eaa03..9cae6cf5e7665 100644 --- a/src/test/ui/issues/issue-37051.rs +++ b/src/test/ui/issues/issue-37051.rs @@ -1,5 +1,4 @@ // check-pass -// ignore-compare-mode-chalk #![feature(associated_type_defaults)] diff --git a/src/test/ui/issues/issue-55796.rs b/src/test/ui/issues/issue-55796.rs index 1086669ee7463..d802ce3b6cfbf 100644 --- a/src/test/ui/issues/issue-55796.rs +++ b/src/test/ui/issues/issue-55796.rs @@ -1,5 +1,3 @@ -// ignore-compare-mode-chalk - pub trait EdgeTrait { fn target(&self) -> N; } @@ -16,12 +14,12 @@ pub trait Graph<'a> { fn out_neighbors(&'a self, u: &Self::Node) -> Box> { Box::new(self.out_edges(u).map(|e| e.target())) -//~^ ERROR cannot infer + //~^ ERROR cannot infer } fn in_neighbors(&'a self, u: &Self::Node) -> Box> { Box::new(self.in_edges(u).map(|e| e.target())) -//~^ ERROR cannot infer + //~^ ERROR cannot infer } } diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr index 304339657f0a9..569a13f45bce8 100644 --- a/src/test/ui/issues/issue-55796.stderr +++ b/src/test/ui/issues/issue-55796.stderr @@ -1,22 +1,22 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/issue-55796.rs:18:9 + --> $DIR/issue-55796.rs:16:9 | LL | Box::new(self.out_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... - --> $DIR/issue-55796.rs:7:17 + --> $DIR/issue-55796.rs:5:17 | LL | pub trait Graph<'a> { | ^^ -note: ...so that the type `Map<>::EdgesIter, [closure@$DIR/issue-55796.rs:18:40: 18:54]>` will meet its required lifetime bounds - --> $DIR/issue-55796.rs:18:9 +note: ...so that the type `Map<>::EdgesIter, [closure@$DIR/issue-55796.rs:16:40: 16:54]>` will meet its required lifetime bounds + --> $DIR/issue-55796.rs:16:9 | LL | Box::new(self.out_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: but, the lifetime must be valid for the static lifetime... note: ...so that the types are compatible - --> $DIR/issue-55796.rs:18:9 + --> $DIR/issue-55796.rs:16:9 | LL | Box::new(self.out_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,24 +24,24 @@ LL | Box::new(self.out_edges(u).map(|e| e.target())) found `Box>::Node>>` error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/issue-55796.rs:23:9 + --> $DIR/issue-55796.rs:21:9 | LL | Box::new(self.in_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... - --> $DIR/issue-55796.rs:7:17 + --> $DIR/issue-55796.rs:5:17 | LL | pub trait Graph<'a> { | ^^ -note: ...so that the type `Map<>::EdgesIter, [closure@$DIR/issue-55796.rs:23:39: 23:53]>` will meet its required lifetime bounds - --> $DIR/issue-55796.rs:23:9 +note: ...so that the type `Map<>::EdgesIter, [closure@$DIR/issue-55796.rs:21:39: 21:53]>` will meet its required lifetime bounds + --> $DIR/issue-55796.rs:21:9 | LL | Box::new(self.in_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: but, the lifetime must be valid for the static lifetime... note: ...so that the types are compatible - --> $DIR/issue-55796.rs:23:9 + --> $DIR/issue-55796.rs:21:9 | LL | Box::new(self.in_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs b/src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs index 44ea9f12d38ff..36e9932602fb0 100644 --- a/src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs +++ b/src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs @@ -1,6 +1,5 @@ // build-pass // ignore-tidy-filelength -// ignore-compare-mode-chalk #![crate_type = "rlib"] fn banana(v: &str) -> u32 { diff --git a/src/test/ui/nll/ty-outlives/issue-53789-2.rs b/src/test/ui/nll/ty-outlives/issue-53789-2.rs index d15e402460794..5109a0e4a683d 100644 --- a/src/test/ui/nll/ty-outlives/issue-53789-2.rs +++ b/src/test/ui/nll/ty-outlives/issue-53789-2.rs @@ -1,16 +1,14 @@ // Regression test for #53789. // // check-pass -// ignore-compare-mode-chalk +use std::cmp::Ord; use std::collections::BTreeMap; use std::ops::Range; -use std::cmp::Ord; macro_rules! valuetree { () => { - type ValueTree = - ::Value; + type ValueTree = ::Value; }; } @@ -41,7 +39,9 @@ macro_rules! product_type { macro_rules! default { ($type: ty, $val: expr) => { impl Default for $type { - fn default() -> Self { $val.into() } + fn default() -> Self { + $val.into() + } } }; } @@ -90,21 +90,17 @@ trait ValueTree { } trait Strategy { - type Value : ValueTree; + type Value: ValueTree; } #[derive(Clone)] -struct VecStrategy { +struct VecStrategy { element: T, size: Range, } -fn vec(element: T, size: Range) - -> VecStrategy { - VecStrategy { - element: element, - size: size, - } +fn vec(element: T, size: Range) -> VecStrategy { + VecStrategy { element: element, size: size } } type ValueFor = <::Value as ValueTree>::Value; @@ -124,7 +120,6 @@ type StrategyType<'a, A> = >::Strategy; struct SizeBounds(Range); default!(SizeBounds, 0..100); - impl From> for SizeBounds { fn from(high: Range) -> Self { unimplemented!() @@ -137,24 +132,26 @@ impl From for Range { } } - -fn any_with<'a, A: Arbitrary<'a>>(args: A::Parameters) - -> StrategyType<'a, A> { +fn any_with<'a, A: Arbitrary<'a>>(args: A::Parameters) -> StrategyType<'a, A> { unimplemented!() } -impl Strategy for (K, V) where - ::Value: Ord { +impl Strategy for (K, V) +where + ::Value: Ord, +{ type Value = TupleValueTree<(K, V)>; } -impl ValueTree for TupleValueTree<(K, V)> where - ::Value: Ord { +impl ValueTree for TupleValueTree<(K, V)> +where + ::Value: Ord, +{ type Value = BTreeMapValueTree; } #[derive(Clone)] -struct VecValueTree { +struct VecValueTree { elements: Vec, } @@ -185,8 +182,8 @@ impl<'a, A, B> Arbitrary<'a> for BTreeMap where A: Arbitrary<'static> + Ord, B: Arbitrary<'static>, -StrategyFor: 'static, -StrategyFor: 'static, + StrategyFor: 'static, + StrategyFor: 'static, { valuetree!(); type Parameters = RangedParams2; @@ -208,10 +205,14 @@ mapfn! { } } -fn btree_map - (key: K, value: V, size: Range) - -> BTreeMapStrategy -where ValueFor : Ord { +fn btree_map( + key: K, + value: V, + size: Range, +) -> BTreeMapStrategy +where + ValueFor: Ord, +{ unimplemented!() } @@ -245,4 +246,4 @@ mod statics { } } -fn main() { } +fn main() {} diff --git a/src/test/ui/parser/issues/issue-93282.rs b/src/test/ui/parser/issues/issue-93282.rs index 7be8b25363e09..261fcb5f9183e 100644 --- a/src/test/ui/parser/issues/issue-93282.rs +++ b/src/test/ui/parser/issues/issue-93282.rs @@ -1,4 +1,15 @@ fn main() { f<'a,> //~^ ERROR expected + //~| ERROR expected +} + +fn bar(a: usize, b: usize) -> usize { + a + b +} + +fn foo() { + let x = 1; + bar('y, x); + //~^ ERROR expected } diff --git a/src/test/ui/parser/issues/issue-93282.stderr b/src/test/ui/parser/issues/issue-93282.stderr index 20e6c3ed8a8d5..900f21a7ccef4 100644 --- a/src/test/ui/parser/issues/issue-93282.stderr +++ b/src/test/ui/parser/issues/issue-93282.stderr @@ -1,3 +1,9 @@ +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/issue-93282.rs:2:9 + | +LL | f<'a,> + | ^ expected `while`, `for`, `loop` or `{` after a label + error: expected one of `.`, `:`, `;`, `?`, `for`, `loop`, `while`, `{`, `}`, or an operator, found `,` --> $DIR/issue-93282.rs:2:9 | @@ -9,5 +15,11 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum LL | f::<'a,> | ++ -error: aborting due to previous error +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/issue-93282.rs:13:11 + | +LL | bar('y, x); + | ^ expected `while`, `for`, `loop` or `{` after a label + +error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.rs b/src/test/ui/parser/require-parens-for-chained-comparison.rs index 68636f6b907ef..f29fd7a5472d4 100644 --- a/src/test/ui/parser/require-parens-for-chained-comparison.rs +++ b/src/test/ui/parser/require-parens-for-chained-comparison.rs @@ -22,10 +22,12 @@ fn main() { let _ = f<'_, i8>(); //~^ ERROR expected one of //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + //~| ERROR expected f<'_>(); //~^ comparison operators cannot be chained //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + //~| ERROR expected let _ = f; //~^ ERROR comparison operators cannot be chained diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.stderr b/src/test/ui/parser/require-parens-for-chained-comparison.stderr index cde6f8c674f4b..92d700753dc1b 100644 --- a/src/test/ui/parser/require-parens-for-chained-comparison.stderr +++ b/src/test/ui/parser/require-parens-for-chained-comparison.stderr @@ -53,6 +53,12 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum LL | let _ = f::(); | ++ +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/require-parens-for-chained-comparison.rs:22:17 + | +LL | let _ = f<'_, i8>(); + | ^ expected `while`, `for`, `loop` or `{` after a label + error: expected one of `.`, `:`, `;`, `?`, `else`, `for`, `loop`, `while`, `{`, or an operator, found `,` --> $DIR/require-parens-for-chained-comparison.rs:22:17 | @@ -64,8 +70,14 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum LL | let _ = f::<'_, i8>(); | ++ +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/require-parens-for-chained-comparison.rs:27:9 + | +LL | f<'_>(); + | ^ expected `while`, `for`, `loop` or `{` after a label + error: comparison operators cannot be chained - --> $DIR/require-parens-for-chained-comparison.rs:26:6 + --> $DIR/require-parens-for-chained-comparison.rs:27:6 | LL | f<'_>(); | ^ ^ @@ -76,7 +88,7 @@ LL | f::<'_>(); | ++ error: comparison operators cannot be chained - --> $DIR/require-parens-for-chained-comparison.rs:30:14 + --> $DIR/require-parens-for-chained-comparison.rs:32:14 | LL | let _ = f; | ^ ^ @@ -84,5 +96,5 @@ LL | let _ = f; = help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments = help: or use `(...)` if you meant to specify fn arguments -error: aborting due to 8 previous errors +error: aborting due to 10 previous errors diff --git a/src/test/ui/specialization/deafult-associated-type-bound-1.rs b/src/test/ui/specialization/default-associated-type-bound-1.rs similarity index 95% rename from src/test/ui/specialization/deafult-associated-type-bound-1.rs rename to src/test/ui/specialization/default-associated-type-bound-1.rs index 6eb2aa980d152..c043114b565c8 100644 --- a/src/test/ui/specialization/deafult-associated-type-bound-1.rs +++ b/src/test/ui/specialization/default-associated-type-bound-1.rs @@ -1,6 +1,5 @@ // Check that we check that default associated types satisfy the required // bounds on them. -// ignore-compare-mode-chalk #![feature(specialization)] //~^ WARNING `specialization` is incomplete diff --git a/src/test/ui/specialization/deafult-associated-type-bound-1.stderr b/src/test/ui/specialization/default-associated-type-bound-1.stderr similarity index 84% rename from src/test/ui/specialization/deafult-associated-type-bound-1.stderr rename to src/test/ui/specialization/default-associated-type-bound-1.stderr index 9e400f8702474..6680a29f94245 100644 --- a/src/test/ui/specialization/deafult-associated-type-bound-1.stderr +++ b/src/test/ui/specialization/default-associated-type-bound-1.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/deafult-associated-type-bound-1.rs:5:12 + --> $DIR/default-associated-type-bound-1.rs:4:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/deafult-associated-type-bound-1.rs:19:22 + --> $DIR/default-associated-type-bound-1.rs:18:22 | LL | default type U = str; | ^^^ the trait `Clone` is not implemented for `str` | note: required by a bound in `X::U` - --> $DIR/deafult-associated-type-bound-1.rs:9:13 + --> $DIR/default-associated-type-bound-1.rs:8:13 | LL | type U: Clone; | ^^^^^ required by this bound in `X::U` diff --git a/src/test/ui/specialization/deafult-associated-type-bound-2.rs b/src/test/ui/specialization/default-associated-type-bound-2.rs similarity index 100% rename from src/test/ui/specialization/deafult-associated-type-bound-2.rs rename to src/test/ui/specialization/default-associated-type-bound-2.rs diff --git a/src/test/ui/specialization/deafult-associated-type-bound-2.stderr b/src/test/ui/specialization/default-associated-type-bound-2.stderr similarity index 88% rename from src/test/ui/specialization/deafult-associated-type-bound-2.stderr rename to src/test/ui/specialization/default-associated-type-bound-2.stderr index 47ea69d40bbb7..0fd1f65b0a201 100644 --- a/src/test/ui/specialization/deafult-associated-type-bound-2.stderr +++ b/src/test/ui/specialization/default-associated-type-bound-2.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/deafult-associated-type-bound-2.rs:2:12 + --> $DIR/default-associated-type-bound-2.rs:2:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -9,14 +9,14 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete error[E0277]: can't compare `&'static B` with `B` - --> $DIR/deafult-associated-type-bound-2.rs:16:22 + --> $DIR/default-associated-type-bound-2.rs:16:22 | LL | default type U = &'static B; | ^^^^^^^^^^ no implementation for `&'static B == B` | = help: the trait `PartialEq` is not implemented for `&'static B` note: required by a bound in `X::U` - --> $DIR/deafult-associated-type-bound-2.rs:6:13 + --> $DIR/default-associated-type-bound-2.rs:6:13 | LL | type U: PartialEq; | ^^^^^^^^^^^^ required by this bound in `X::U` diff --git a/src/test/ui/specialization/deafult-generic-associated-type-bound.rs b/src/test/ui/specialization/default-generic-associated-type-bound.rs similarity index 100% rename from src/test/ui/specialization/deafult-generic-associated-type-bound.rs rename to src/test/ui/specialization/default-generic-associated-type-bound.rs diff --git a/src/test/ui/specialization/deafult-generic-associated-type-bound.stderr b/src/test/ui/specialization/default-generic-associated-type-bound.stderr similarity index 86% rename from src/test/ui/specialization/deafult-generic-associated-type-bound.stderr rename to src/test/ui/specialization/default-generic-associated-type-bound.stderr index da5fe97cf1b8b..58c6667c8c7ad 100644 --- a/src/test/ui/specialization/deafult-generic-associated-type-bound.stderr +++ b/src/test/ui/specialization/default-generic-associated-type-bound.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/deafult-generic-associated-type-bound.rs:3:12 + --> $DIR/default-generic-associated-type-bound.rs:3:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -9,14 +9,14 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete error[E0277]: can't compare `T` with `T` - --> $DIR/deafult-generic-associated-type-bound.rs:18:26 + --> $DIR/default-generic-associated-type-bound.rs:18:26 | LL | default type U<'a> = &'a T; | ^^^^^ no implementation for `T == T` | = note: required because of the requirements on the impl of `PartialEq` for `&'a T` note: required by a bound in `X::U` - --> $DIR/deafult-generic-associated-type-bound.rs:8:17 + --> $DIR/default-generic-associated-type-bound.rs:8:17 | LL | type U<'a>: PartialEq<&'a Self> where Self: 'a; | ^^^^^^^^^^^^^^^^^^^ required by this bound in `X::U` diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.rs b/src/test/ui/type-alias-impl-trait/issue-53598.rs index 37b330ba4b8fc..f936dc42f133d 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53598.rs +++ b/src/test/ui/type-alias-impl-trait/issue-53598.rs @@ -1,4 +1,3 @@ -// ignore-compare-mode-chalk #![feature(type_alias_impl_trait)] use std::fmt::Debug; diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.stderr b/src/test/ui/type-alias-impl-trait/issue-53598.stderr index 4c8144a235930..9971c7e0e20ee 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53598.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-53598.stderr @@ -1,5 +1,5 @@ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-53598.rs:20:42 + --> $DIR/issue-53598.rs:19:42 | LL | fn foo(_: T) -> Self::Item { | __________________________________________^ diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.rs b/src/test/ui/type-alias-impl-trait/issue-57700.rs index f1db4d3291b40..13a6b7c2f7ceb 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57700.rs +++ b/src/test/ui/type-alias-impl-trait/issue-57700.rs @@ -1,4 +1,3 @@ -// ignore-compare-mode-chalk #![feature(arbitrary_self_types)] #![feature(type_alias_impl_trait)] diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.stderr b/src/test/ui/type-alias-impl-trait/issue-57700.stderr index c701e3e74ef59..b2e3f46f1f582 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57700.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57700.stderr @@ -1,5 +1,5 @@ error: type parameter `impl Deref` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-57700.rs:16:58 + --> $DIR/issue-57700.rs:15:58 | LL | fn foo(self: impl Deref) -> Self::Bar { | __________________________________________________________^ diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs index 9d2ba849c8667..badf35484f360 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs @@ -1,5 +1,3 @@ -// ignore-compare-mode-chalk - trait Bug { type Item: Bug; diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr index 62ab7eb456010..dc8a381aece94 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr @@ -1,5 +1,5 @@ error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/issue-60371.rs:10:17 + --> $DIR/issue-60371.rs:8:17 | LL | type Item = impl Bug; | ^^^^^^^^ @@ -8,7 +8,7 @@ LL | type Item = impl Bug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0277]: the trait bound `(): Bug` is not satisfied - --> $DIR/issue-60371.rs:12:40 + --> $DIR/issue-60371.rs:10:40 | LL | const FUN: fn() -> Self::Item = || (); | ^ the trait `Bug` is not implemented for `()` @@ -17,7 +17,7 @@ LL | const FUN: fn() -> Self::Item = || (); <&() as Bug> error: non-defining opaque type use in defining scope - --> $DIR/issue-60371.rs:12:37 + --> $DIR/issue-60371.rs:10:37 | LL | impl Bug for &() { | - cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 94e82e3d9f766..46daaf42883f0 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -182,8 +182,9 @@ impl Checker { fn walk(&mut self, dir: &Path, report: &mut Report) { for entry in t!(dir.read_dir()).map(|e| t!(e)) { let path = entry.path(); - let kind = t!(entry.file_type()); - if kind.is_dir() { + // Goes through symlinks + let metadata = t!(fs::metadata(&path)); + if metadata.is_dir() { self.walk(&path, report); } else { self.check(&path, report); diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs index 8ea6bb308b7ba..2a23d72edc064 100644 --- a/src/tools/tidy/src/error_codes_check.rs +++ b/src/tools/tidy/src/error_codes_check.rs @@ -1,7 +1,7 @@ //! Checks that all error codes have at least one test to prevent having error //! codes that are silently not thrown by the compiler anymore. -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::ffi::OsStr; use std::fs::read_to_string; use std::path::Path; @@ -205,6 +205,7 @@ pub fn check(paths: &[&Path], bad: &mut bool) { let mut found_explanations = 0; let mut found_tests = 0; let mut error_codes: HashMap = HashMap::new(); + let mut explanations: HashSet = HashSet::new(); // We want error codes which match the following cases: // // * foo(a, E0111, a) @@ -218,17 +219,27 @@ pub fn check(paths: &[&Path], bad: &mut bool) { for path in paths { super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| { let file_name = entry.file_name(); + let entry_path = entry.path(); + if file_name == "error_codes.rs" { extract_error_codes(contents, &mut error_codes, entry.path(), &mut errors); found_explanations += 1; - } else if entry.path().extension() == Some(OsStr::new("stderr")) { + } else if entry_path.extension() == Some(OsStr::new("stderr")) { extract_error_codes_from_tests(contents, &mut error_codes); found_tests += 1; - } else if entry.path().extension() == Some(OsStr::new("rs")) { + } else if entry_path.extension() == Some(OsStr::new("rs")) { let path = entry.path().to_string_lossy(); if PATHS_TO_IGNORE_FOR_EXTRACTION.iter().all(|c| !path.contains(c)) { extract_error_codes_from_source(contents, &mut error_codes, ®ex); } + } else if entry_path + .parent() + .and_then(|p| p.file_name()) + .map(|p| p == "error_codes") + .unwrap_or(false) + && entry_path.extension() == Some(OsStr::new("md")) + { + explanations.insert(file_name.to_str().unwrap().replace(".md", "")); } }); } @@ -240,6 +251,10 @@ pub fn check(paths: &[&Path], bad: &mut bool) { eprintln!("No error code was found in compilation errors!"); *bad = true; } + if explanations.is_empty() { + eprintln!("No error code explanation was found!"); + *bad = true; + } if errors.is_empty() { println!("Found {} error codes", error_codes.len()); @@ -282,11 +297,21 @@ pub fn check(paths: &[&Path], bad: &mut bool) { } } } + if errors.is_empty() { + for explanation in explanations { + if !error_codes.contains_key(&explanation) { + errors.push(format!( + "{} error code explanation should be listed in `error_codes.rs`", + explanation + )); + } + } + } errors.sort(); for err in &errors { eprintln!("{}", err); } - println!("Found {} error codes with no tests", errors.len()); + println!("Found {} error(s) in error codes", errors.len()); if !errors.is_empty() { *bad = true; }