From 474b16b00220da77cb811c646de0f05c8b9d80f8 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 28 May 2020 16:08:46 -0300 Subject: [PATCH 01/20] Add windows group to triagebot --- triagebot.toml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index e43cff55386..3a52cda81c9 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -36,6 +36,16 @@ Thanks! <3 """ label = "ICEBreaker-Cleanup-Crew" +[ping.windows] +message = """\ +Hey Windows Group! This bug has been identified as a good "Windows candidate". +In case it's useful, here are some [instructions] for tackling these sorts of +bugs. Maybe take a look? +Thanks! <3 +[instructions]: https://rust-lang.github.io/rustc-guide/notification-groups/windows.html +""" +label = "O-windows" + [prioritize] label = "I-prioritize" prioritize_on = ["regression-from-stable-to-stable", "regression-from-stable-to-beta", "regression-from-stable-to-nightly"] From 52f1847bca00890aaf424634f9c0f52960866ee0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 30 May 2020 19:54:44 +0300 Subject: [PATCH 02/20] resolve: Pass parent scope to the function providing import suggestions --- src/librustc_resolve/diagnostics.rs | 4 ++++ src/librustc_resolve/late/diagnostics.rs | 5 +++-- src/librustc_resolve/lib.rs | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index ea237f1a04f..176204affde 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -629,6 +629,7 @@ impl<'a> Resolver<'a> { &mut self, lookup_ident: Ident, namespace: Namespace, + _parent_scope: &ParentScope<'a>, start_module: Module<'a>, crate_name: Ident, filter_fn: FilterFn, @@ -722,6 +723,7 @@ impl<'a> Resolver<'a> { &mut self, lookup_ident: Ident, namespace: Namespace, + parent_scope: &ParentScope<'a>, filter_fn: FilterFn, ) -> Vec where @@ -730,6 +732,7 @@ impl<'a> Resolver<'a> { let mut suggestions = self.lookup_import_candidates_from_module( lookup_ident, namespace, + parent_scope, self.graph_root, Ident::with_dummy_span(kw::Crate), &filter_fn, @@ -754,6 +757,7 @@ impl<'a> Resolver<'a> { suggestions.extend(self.lookup_import_candidates_from_module( lookup_ident, namespace, + parent_scope, crate_root, ident, &filter_fn, diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index b1a1f8725a1..ed7adefcb8c 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -212,7 +212,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { let ident = path.last().unwrap().ident; let candidates = self .r - .lookup_import_candidates(ident, ns, is_expected) + .lookup_import_candidates(ident, ns, &self.parent_scope, is_expected) .drain(..) .filter(|ImportSuggestion { did, .. }| { match (did, res.and_then(|res| res.opt_def_id())) { @@ -223,7 +223,8 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { .collect::>(); let crate_def_id = DefId::local(CRATE_DEF_INDEX); if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) { - let enum_candidates = self.r.lookup_import_candidates(ident, ns, is_enum_variant); + let enum_candidates = + self.r.lookup_import_candidates(ident, ns, &self.parent_scope, is_enum_variant); let mut enum_candidates = enum_candidates .iter() .map(|suggestion| import_candidate_to_enum_paths(&suggestion)) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b50f9fe8e90..3d6b0ea98bf 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2256,7 +2256,8 @@ impl<'a> Resolver<'a> { Res::Def(DefKind::Mod, _) => true, _ => false, }; - let mut candidates = self.lookup_import_candidates(ident, TypeNS, is_mod); + let mut candidates = + self.lookup_import_candidates(ident, TypeNS, parent_scope, is_mod); candidates.sort_by_cached_key(|c| { (c.path.segments.len(), pprust::path_to_string(&c.path)) }); From 21fca7aae7213b651399e95d3d83f85f00734036 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 30 May 2020 20:11:14 +0300 Subject: [PATCH 03/20] resolve: Do not suggest imports from the same module in which we are resolving --- src/librustc_resolve/diagnostics.rs | 8 ++++++-- src/test/ui/lexical-scopes.stderr | 5 ----- src/test/ui/proc-macro/mixed-site-span.stderr | 4 ---- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 176204affde..a952e08c2d6 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -629,7 +629,7 @@ impl<'a> Resolver<'a> { &mut self, lookup_ident: Ident, namespace: Namespace, - _parent_scope: &ParentScope<'a>, + parent_scope: &ParentScope<'a>, start_module: Module<'a>, crate_name: Ident, filter_fn: FilterFn, @@ -656,7 +656,11 @@ impl<'a> Resolver<'a> { } // collect results based on the filter function - if ident.name == lookup_ident.name && ns == namespace { + // avoid suggesting anything from the same module in which we are resolving + if ident.name == lookup_ident.name + && ns == namespace + && !ptr::eq(in_module, parent_scope.module) + { let res = name_binding.res(); if filter_fn(res) { // create the path diff --git a/src/test/ui/lexical-scopes.stderr b/src/test/ui/lexical-scopes.stderr index dce70545170..1e6a35ed479 100644 --- a/src/test/ui/lexical-scopes.stderr +++ b/src/test/ui/lexical-scopes.stderr @@ -3,11 +3,6 @@ error[E0574]: expected struct, variant or union type, found type parameter `T` | LL | let t = T { i: 0 }; | ^ not a struct, variant or union type - | -help: consider importing this struct instead - | -LL | use T; - | error[E0599]: no function or associated item named `f` found for type parameter `Foo` in the current scope --> $DIR/lexical-scopes.rs:10:10 diff --git a/src/test/ui/proc-macro/mixed-site-span.stderr b/src/test/ui/proc-macro/mixed-site-span.stderr index 2b851a76f6a..6244ffc47a6 100644 --- a/src/test/ui/proc-macro/mixed-site-span.stderr +++ b/src/test/ui/proc-macro/mixed-site-span.stderr @@ -27,10 +27,6 @@ LL | pass_dollar_crate!(); | ^^^^^^^^^^^^^^^^^^^^^ not found in `$crate` | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider importing this struct - | -LL | use ItemUse; - | error: aborting due to 4 previous errors From 29508ce3ad7cf5c886f475d00148b076857bf93c Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Tue, 2 Jun 2020 00:23:47 +0200 Subject: [PATCH 04/20] normalize adt fields during structural match check --- .../traits/structural_match.rs | 6 ++++- src/test/ui/match/issue-72896.rs | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/match/issue-72896.rs diff --git a/src/librustc_trait_selection/traits/structural_match.rs b/src/librustc_trait_selection/traits/structural_match.rs index b877049fcf6..dd711b9e256 100644 --- a/src/librustc_trait_selection/traits/structural_match.rs +++ b/src/librustc_trait_selection/traits/structural_match.rs @@ -251,7 +251,11 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> { // fields of ADT. let tcx = self.tcx(); for field_ty in adt_def.all_fields().map(|field| field.ty(tcx, substs)) { - if field_ty.visit_with(self) { + assert!(!field_ty.needs_subst()); + let ty = self.tcx().normalize_erasing_regions(ty::ParamEnv::reveal_all(), field_ty); + debug!("structural-match ADT: field_ty={:?}, ty={:?}", field_ty, ty); + + if ty.visit_with(self) { // found an ADT without structural-match; halt visiting! assert!(self.found.is_some()); return true; diff --git a/src/test/ui/match/issue-72896.rs b/src/test/ui/match/issue-72896.rs new file mode 100644 index 00000000000..3a8b8203731 --- /dev/null +++ b/src/test/ui/match/issue-72896.rs @@ -0,0 +1,23 @@ +// run-pass +trait EnumSetType { + type Repr; +} + +enum Enum8 { } +impl EnumSetType for Enum8 { + type Repr = u8; +} + +#[derive(PartialEq, Eq)] +struct EnumSet { + __enumset_underlying: T::Repr, +} + +const CONST_SET: EnumSet = EnumSet { __enumset_underlying: 3 }; + +fn main() { + match CONST_SET { + CONST_SET => { /* ok */ } + _ => panic!("match fell through?"), + } +} From 4725af38bc51760ad36180ebd7d128481b3d8ccc Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Tue, 2 Jun 2020 09:31:10 +0200 Subject: [PATCH 05/20] remove assert --- src/librustc_trait_selection/traits/structural_match.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_trait_selection/traits/structural_match.rs b/src/librustc_trait_selection/traits/structural_match.rs index dd711b9e256..87ff667b6a0 100644 --- a/src/librustc_trait_selection/traits/structural_match.rs +++ b/src/librustc_trait_selection/traits/structural_match.rs @@ -251,8 +251,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> { // fields of ADT. let tcx = self.tcx(); for field_ty in adt_def.all_fields().map(|field| field.ty(tcx, substs)) { - assert!(!field_ty.needs_subst()); - let ty = self.tcx().normalize_erasing_regions(ty::ParamEnv::reveal_all(), field_ty); + let ty = self.tcx().normalize_erasing_regions(ty::ParamEnv::empty(), field_ty); debug!("structural-match ADT: field_ty={:?}, ty={:?}", field_ty, ty); if ty.visit_with(self) { From 7f7729d83be2ff8e9e933b94ff02f1bb77d688f8 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 4 Jun 2020 19:32:09 -0400 Subject: [PATCH 06/20] Don't create impl candidates when obligation contains errors Fixes #72839 In PR #72621, trait selection was modified to no longer bail out early when an error type was encountered. This allowed us treat `ty::Error` as `Sized`, causing us to avoid emitting a spurious "not sized" error after a type error had already occured. However, this means that we may now try to match an impl candidate against the error type. Since the error type will unify with almost anything, this can cause us to infinitely recurse (eventually triggering an overflow) when trying to verify certain `where` clauses. This commit causes us to skip generating any impl candidates when an error type is involved. --- .../traits/select/candidate_assembly.rs | 10 ++++++++++ .../ui/issues/issue-72839-error-overflow.rs | 19 +++++++++++++++++++ .../issues/issue-72839-error-overflow.stderr | 9 +++++++++ 3 files changed, 38 insertions(+) create mode 100644 src/test/ui/issues/issue-72839-error-overflow.rs create mode 100644 src/test/ui/issues/issue-72839-error-overflow.stderr diff --git a/src/librustc_trait_selection/traits/select/candidate_assembly.rs b/src/librustc_trait_selection/traits/select/candidate_assembly.rs index d42c31a5474..2bd0acb3cc0 100644 --- a/src/librustc_trait_selection/traits/select/candidate_assembly.rs +++ b/src/librustc_trait_selection/traits/select/candidate_assembly.rs @@ -331,6 +331,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result<(), SelectionError<'tcx>> { debug!("assemble_candidates_from_impls(obligation={:?})", obligation); + // Essentially any user-written impl will match with an error type, + // so creating `ImplCandidates` isn't useful. However, we might + // end up finding a candidate elsewhere (e.g. a `BuiltinCandidate` for `Sized) + // This helps us avoid overflow: see issue #72839 + // Since compilation is already guarnateed to fail, this is just + // to try to show the 'nicest' possible errors to the user. + if obligation.references_error() { + return Ok(()); + } + self.tcx().for_each_relevant_impl( obligation.predicate.def_id(), obligation.predicate.skip_binder().trait_ref.self_ty(), diff --git a/src/test/ui/issues/issue-72839-error-overflow.rs b/src/test/ui/issues/issue-72839-error-overflow.rs new file mode 100644 index 00000000000..6562d228409 --- /dev/null +++ b/src/test/ui/issues/issue-72839-error-overflow.rs @@ -0,0 +1,19 @@ +// Regression test for issue #72839 +// Tests that we do not overflow during trait selection after +// a type error occurs +use std::ops::Rem; +trait Foo {} +struct MyStruct(T); + +impl Rem> for MyStruct where MyStruct: Rem> { + type Output = u8; + fn rem(self, _: MyStruct) -> Self::Output { + panic!() + } +} + +fn main() {} + +fn foo() { + if missing_var % 8 == 0 {} //~ ERROR cannot find +} diff --git a/src/test/ui/issues/issue-72839-error-overflow.stderr b/src/test/ui/issues/issue-72839-error-overflow.stderr new file mode 100644 index 00000000000..c4b6f90ca69 --- /dev/null +++ b/src/test/ui/issues/issue-72839-error-overflow.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `missing_var` in this scope + --> $DIR/issue-72839-error-overflow.rs:18:8 + | +LL | if missing_var % 8 == 0 {} + | ^^^^^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. From 3295c262aea18f64b80734989ab522e1278a9d14 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 4 Jun 2020 21:09:31 -0400 Subject: [PATCH 07/20] Treat selection error as ambiguous when error type is present --- .../traits/select/mod.rs | 8 + src/test/ui/impl-trait/auto-trait-leak.rs | 2 - src/test/ui/impl-trait/auto-trait-leak.stderr | 188 +----------------- 3 files changed, 17 insertions(+), 181 deletions(-) diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs index def99a7b5b5..7ebf30f61c0 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/src/librustc_trait_selection/traits/select/mod.rs @@ -1104,6 +1104,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // who might care about this case, like coherence, should use // that function). if candidates.is_empty() { + // If there's an error type, 'downgrade' our result from + // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid + // emitting additional spurious errors, since we're guaranteed + // to have emitted at least one. + if stack.obligation.references_error() { + debug!("no results for error type, treating as ambiguous"); + return Ok(None); + } return Err(Unimplemented); } diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs index a6012835f44..087f4582b21 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.rs +++ b/src/test/ui/impl-trait/auto-trait-leak.rs @@ -11,8 +11,6 @@ fn main() { // return type, which can't depend on the obligation. fn cycle1() -> impl Clone { //~^ ERROR cycle detected - //~| ERROR cycle detected - //~| ERROR cycle detected send(cycle2().clone()); //~^ ERROR cannot be sent between threads safely diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index 64d02f07048..679b26efe59 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -36,37 +36,37 @@ LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... note: ...which requires computing type of `cycle2::{{opaque}}#0`... - --> $DIR/auto-trait-leak.rs:22:16 + --> $DIR/auto-trait-leak.rs:20:16 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^ note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,178 +84,8 @@ LL | | Rc::new(String::from("foo")) LL | | } | |_^ -error[E0391]: cycle detected when computing type of `cycle1::{{opaque}}#0` - --> $DIR/auto-trait-leak.rs:12:16 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^ - | -note: ...which requires borrow-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... -note: ...which requires computing type of `cycle2::{{opaque}}#0`... - --> $DIR/auto-trait-leak.rs:22:16 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^ -note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `cycle1::{{opaque}}#0`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/auto-trait-leak.rs:1:1 - | -LL | / use std::cell::Cell; -LL | | use std::rc::Rc; -LL | | -LL | | fn send(_: T) {} -... | -LL | | Rc::new(String::from("foo")) -LL | | } - | |_^ - -error[E0391]: cycle detected when computing type of `cycle1::{{opaque}}#0` - --> $DIR/auto-trait-leak.rs:12:16 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^ - | -note: ...which requires borrow-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... -note: ...which requires computing type of `cycle2::{{opaque}}#0`... - --> $DIR/auto-trait-leak.rs:22:16 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^ -note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `cycle1::{{opaque}}#0`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/auto-trait-leak.rs:1:1 - | -LL | / use std::cell::Cell; -LL | | use std::rc::Rc; -LL | | -LL | | fn send(_: T) {} -... | -LL | | Rc::new(String::from("foo")) -LL | | } - | |_^ - error[E0277]: `std::rc::Rc` cannot be sent between threads safely - --> $DIR/auto-trait-leak.rs:16:5 + --> $DIR/auto-trait-leak.rs:14:5 | LL | fn send(_: T) {} | ---- required by this bound in `send` @@ -269,7 +99,7 @@ LL | fn cycle2() -> impl Clone { = help: within `impl std::clone::Clone`, the trait `std::marker::Send` is not implemented for `std::rc::Rc` = note: required because it appears within the type `impl std::clone::Clone` -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0391. For more information about an error, try `rustc --explain E0277`. From ae42c91c6517517e831b12e0f4a98d538b4a19b5 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 5 Jun 2020 18:57:17 -0400 Subject: [PATCH 08/20] Fix typo Co-authored-by: Randy Taylor --- .../traits/select/candidate_assembly.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trait_selection/traits/select/candidate_assembly.rs b/src/librustc_trait_selection/traits/select/candidate_assembly.rs index 2bd0acb3cc0..9045451056b 100644 --- a/src/librustc_trait_selection/traits/select/candidate_assembly.rs +++ b/src/librustc_trait_selection/traits/select/candidate_assembly.rs @@ -335,7 +335,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // so creating `ImplCandidates` isn't useful. However, we might // end up finding a candidate elsewhere (e.g. a `BuiltinCandidate` for `Sized) // This helps us avoid overflow: see issue #72839 - // Since compilation is already guarnateed to fail, this is just + // Since compilation is already guaranteed to fail, this is just // to try to show the 'nicest' possible errors to the user. if obligation.references_error() { return Ok(()); From 568cc22c3d04338f3413af19332a1c31b44dbf77 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sat, 6 Jun 2020 11:44:28 -0700 Subject: [PATCH 09/20] Add regression test for const generic ICE in #72819 Closes #72819 --- .../issues/issue-72819-generic-in-const-eval.rs | 16 ++++++++++++++++ .../issue-72819-generic-in-const-eval.stderr | 10 ++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs create mode 100644 src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs new file mode 100644 index 00000000000..d9cbc815e8b --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs @@ -0,0 +1,16 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] +struct Arr +where Assert::<{N < usize::max_value() / 2}>: IsTrue, //~ ERROR constant expression depends on a generic parameter +{ +} + +enum Assert {} + +trait IsTrue {} + +impl IsTrue for Assert {} + +fn main() { + let x: Arr<{usize::max_value()}> = Arr {}; +} diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr new file mode 100644 index 00000000000..f0b761f114b --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr @@ -0,0 +1,10 @@ +error: constant expression depends on a generic parameter + --> $DIR/issue-72819-generic-in-const-eval.rs:4:47 + | +LL | where Assert::<{N < usize::max_value() / 2}>: IsTrue, + | ^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to previous error + From ab7355a8860b1a16672f3678aebf64cadc53ab18 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sat, 6 Jun 2020 12:00:23 -0700 Subject: [PATCH 10/20] fixup! Add regression test for const generic ICE in #72819 --- .../const-generics/issues/issue-72819-generic-in-const-eval.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs index d9cbc815e8b..6228546057c 100644 --- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs +++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs @@ -1,7 +1,8 @@ #![feature(const_generics)] #![allow(incomplete_features)] struct Arr -where Assert::<{N < usize::max_value() / 2}>: IsTrue, //~ ERROR constant expression depends on a generic parameter +where Assert::<{N < usize::max_value() / 2}>: IsTrue, +//~^ ERROR constant expression depends on a generic parameter { } From f82382af28f8cec77e0c620861fe77ffb47b2c70 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 8 Jun 2020 17:46:28 -0700 Subject: [PATCH 11/20] fixup! Add regression test for const generic ICE in #72819 --- .../const-generics/issues/issue-72819-generic-in-const-eval.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs index 6228546057c..225593c3178 100644 --- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs +++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs @@ -1,3 +1,6 @@ +// Regression test for #72819: ICE due to failure in resolving the const generic in `Arr`'s type +// bounds. + #![feature(const_generics)] #![allow(incomplete_features)] struct Arr From 2981395d0c4c07e4700bfe10168f7df540c2157e Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 8 Jun 2020 18:04:41 -0700 Subject: [PATCH 12/20] fixup! Add regression test for const generic ICE in #72819 --- .../issues/issue-72819-generic-in-const-eval.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr index f0b761f114b..a9f664d0ac8 100644 --- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr +++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr @@ -1,5 +1,5 @@ error: constant expression depends on a generic parameter - --> $DIR/issue-72819-generic-in-const-eval.rs:4:47 + --> $DIR/issue-72819-generic-in-const-eval.rs:7:47 | LL | where Assert::<{N < usize::max_value() / 2}>: IsTrue, | ^^^^^^ From 0fcea2e4238dbb7ba3758064051f6330910aae4c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 8 Jun 2020 21:09:54 -0400 Subject: [PATCH 13/20] Don't lose empty `where` clause when pretty-printing Previously, we would parse `struct Foo where;` and `struct Foo;` identically, leading to an 'empty' `where` clause being omitted during pretty printing. This will cause us to lose spans when proc-macros involved, since we will have a collected `where` token that does not appear in the pretty-printed item. We now explicitly track the presence of a `where` token during parsing, so that we can distinguish between `struct Foo where;` and `struct Foo;` during pretty-printing --- src/librustc_ast/ast.rs | 11 +++++++++- src/librustc_ast/mut_visit.rs | 2 +- src/librustc_ast_pretty/pprust.rs | 8 +++++-- .../deriving/generic/ty.rs | 6 +++++- src/librustc_parse/parser/generics.rs | 9 ++++++-- src/test/ui/proc-macro/empty-where-clause.rs | 18 ++++++++++++++++ .../ui/proc-macro/empty-where-clause.stderr | 21 +++++++++++++++++++ 7 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/proc-macro/empty-where-clause.rs create mode 100644 src/test/ui/proc-macro/empty-where-clause.stderr diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index efcf95ec706..672ef108969 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -362,7 +362,11 @@ impl Default for Generics { fn default() -> Generics { Generics { params: Vec::new(), - where_clause: WhereClause { predicates: Vec::new(), span: DUMMY_SP }, + where_clause: WhereClause { + has_where_token: false, + predicates: Vec::new(), + span: DUMMY_SP, + }, span: DUMMY_SP, } } @@ -371,6 +375,11 @@ impl Default for Generics { /// A where-clause in a definition. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct WhereClause { + /// `true` if we ate a `where` token: this can happen + /// if we parsed no predicates (e.g. `struct Foo where {} + /// This allows us to accurately pretty-print + /// in `nt_to_tokenstream` + pub has_where_token: bool, pub predicates: Vec, pub span: Span, } diff --git a/src/librustc_ast/mut_visit.rs b/src/librustc_ast/mut_visit.rs index 7ececb814a6..66b8d7f97f0 100644 --- a/src/librustc_ast/mut_visit.rs +++ b/src/librustc_ast/mut_visit.rs @@ -786,7 +786,7 @@ pub fn noop_visit_generics(generics: &mut Generics, vis: &mut T) } pub fn noop_visit_where_clause(wc: &mut WhereClause, vis: &mut T) { - let WhereClause { predicates, span } = wc; + let WhereClause { has_where_token: _, predicates, span } = wc; visit_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); vis.visit_span(span); } diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 872126646f3..8ff80df527c 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -2593,7 +2593,7 @@ impl<'a> State<'a> { } crate fn print_where_clause(&mut self, where_clause: &ast::WhereClause) { - if where_clause.predicates.is_empty() { + if where_clause.predicates.is_empty() && !where_clause.has_where_token { return; } @@ -2739,7 +2739,11 @@ impl<'a> State<'a> { } let generics = ast::Generics { params: Vec::new(), - where_clause: ast::WhereClause { predicates: Vec::new(), span: rustc_span::DUMMY_SP }, + where_clause: ast::WhereClause { + has_where_token: false, + predicates: Vec::new(), + span: rustc_span::DUMMY_SP, + }, span: rustc_span::DUMMY_SP, }; let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() }; diff --git a/src/librustc_builtin_macros/deriving/generic/ty.rs b/src/librustc_builtin_macros/deriving/generic/ty.rs index 62cbdb19a88..609feb6f259 100644 --- a/src/librustc_builtin_macros/deriving/generic/ty.rs +++ b/src/librustc_builtin_macros/deriving/generic/ty.rs @@ -216,7 +216,11 @@ fn mk_ty_param( } fn mk_generics(params: Vec, span: Span) -> Generics { - Generics { params, where_clause: ast::WhereClause { predicates: Vec::new(), span }, span } + Generics { + params, + where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), span }, + span, + } } /// Lifetimes and bounds on type parameters diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs index 8e8f864728c..04b64d93c70 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/src/librustc_parse/parser/generics.rs @@ -157,6 +157,7 @@ impl<'a> Parser<'a> { Ok(ast::Generics { params, where_clause: WhereClause { + has_where_token: false, predicates: Vec::new(), span: self.prev_token.span.shrink_to_hi(), }, @@ -170,12 +171,16 @@ impl<'a> Parser<'a> { /// where T : Trait + 'b, 'a : 'b /// ``` pub(super) fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> { - let mut where_clause = - WhereClause { predicates: Vec::new(), span: self.prev_token.span.shrink_to_hi() }; + let mut where_clause = WhereClause { + has_where_token: false, + predicates: Vec::new(), + span: self.prev_token.span.shrink_to_hi(), + }; if !self.eat_keyword(kw::Where) { return Ok(where_clause); } + where_clause.has_where_token = true; let lo = self.prev_token.span; // We are considering adding generics to the `where` keyword as an alternative higher-rank diff --git a/src/test/ui/proc-macro/empty-where-clause.rs b/src/test/ui/proc-macro/empty-where-clause.rs new file mode 100644 index 00000000000..719555c092a --- /dev/null +++ b/src/test/ui/proc-macro/empty-where-clause.rs @@ -0,0 +1,18 @@ +// aux-build:test-macros.rs + +extern crate test_macros; +use test_macros::recollect_attr; + +#[recollect_attr] +struct FieldStruct where { + field: MissingType1 //~ ERROR cannot find +} + +#[recollect_attr] +struct TupleStruct(MissingType2) where; //~ ERROR cannot find + +enum MyEnum where { + Variant(MissingType3) //~ ERROR cannot find +} + +fn main() {} diff --git a/src/test/ui/proc-macro/empty-where-clause.stderr b/src/test/ui/proc-macro/empty-where-clause.stderr new file mode 100644 index 00000000000..192a2b30f0d --- /dev/null +++ b/src/test/ui/proc-macro/empty-where-clause.stderr @@ -0,0 +1,21 @@ +error[E0412]: cannot find type `MissingType1` in this scope + --> $DIR/empty-where-clause.rs:8:12 + | +LL | field: MissingType1 + | ^^^^^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `MissingType2` in this scope + --> $DIR/empty-where-clause.rs:12:20 + | +LL | struct TupleStruct(MissingType2) where; + | ^^^^^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `MissingType3` in this scope + --> $DIR/empty-where-clause.rs:15:13 + | +LL | Variant(MissingType3) + | ^^^^^^^^^^^^ not found in this scope + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0412`. From b05555290ca017e0b40fe6020d69e2177584d5b7 Mon Sep 17 00:00:00 2001 From: Ayush Kumar Mishra Date: Fri, 5 Jun 2020 15:27:37 +0530 Subject: [PATCH 14/20] Remove noisy suggestion of hash_map #72642 Fixed failing test-cases Remove noisy suggestion of hash_map #72642 Fixed failing test-cases --- src/librustc_resolve/diagnostics.rs | 4 +- .../ui/derived-errors/issue-31997-1.stderr | 4 +- .../ui/hygiene/no_implicit_prelude.stderr | 4 +- src/test/ui/issues/issue-17546.stderr | 10 ++-- src/test/ui/no-implicit-prelude-nested.stderr | 48 +++++-------------- src/test/ui/no-implicit-prelude.stderr | 16 ++----- src/test/ui/resolve/use_suggestion.stderr | 8 +--- .../resolve/use_suggestion_placement.stderr | 4 +- 8 files changed, 28 insertions(+), 70 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index cbb2878011c..59fadfc41b0 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -680,7 +680,9 @@ impl<'a> Resolver<'a> { Res::Def(DefKind::Ctor(..), did) => this.parent(did), _ => res.opt_def_id(), }; - candidates.push(ImportSuggestion { did, descr: res.descr(), path }); + if candidates.iter().all(|v: &ImportSuggestion| v.did != did) { + candidates.push(ImportSuggestion { did, descr: res.descr(), path }); + } } } } diff --git a/src/test/ui/derived-errors/issue-31997-1.stderr b/src/test/ui/derived-errors/issue-31997-1.stderr index a4daf86cc8a..229c5c9e80f 100644 --- a/src/test/ui/derived-errors/issue-31997-1.stderr +++ b/src/test/ui/derived-errors/issue-31997-1.stderr @@ -4,12 +4,10 @@ error[E0433]: failed to resolve: use of undeclared type or module `HashMap` LL | let mut map = HashMap::new(); | ^^^^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this struct | LL | use std::collections::HashMap; | -LL | use std::collections::hash_map::HashMap; - | error: aborting due to previous error diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr index c0539434d02..990210ffb6b 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -16,9 +16,7 @@ LL | Vec::new(); | ^^^ not found in this scope | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider importing one of these items - | -LL | use std::prelude::v1::Vec; +help: consider importing this struct | LL | use std::vec::Vec; | diff --git a/src/test/ui/issues/issue-17546.stderr b/src/test/ui/issues/issue-17546.stderr index 8bf40790f0b..95939cf6b38 100644 --- a/src/test/ui/issues/issue-17546.stderr +++ b/src/test/ui/issues/issue-17546.stderr @@ -30,11 +30,10 @@ LL | use std::fmt::Result; | LL | use std::io::Result; | -LL | use std::prelude::v1::Result; - | LL | use std::result::Result; | - and 1 other candidate +LL | use std::thread::Result; + | error[E0573]: expected type, found variant `Result` --> $DIR/issue-17546.rs:30:13 @@ -48,11 +47,10 @@ LL | use std::fmt::Result; | LL | use std::io::Result; | -LL | use std::prelude::v1::Result; - | LL | use std::result::Result; | - and 1 other candidate +LL | use std::thread::Result; + | error[E0573]: expected type, found variant `NoResult` --> $DIR/issue-17546.rs:35:15 diff --git a/src/test/ui/no-implicit-prelude-nested.stderr b/src/test/ui/no-implicit-prelude-nested.stderr index 8a26366d751..198b630c52c 100644 --- a/src/test/ui/no-implicit-prelude-nested.stderr +++ b/src/test/ui/no-implicit-prelude-nested.stderr @@ -15,12 +15,10 @@ error[E0404]: expected trait, found derive macro `Clone` LL | impl Clone for Test {} | ^^^^^ not a trait | -help: consider importing one of these items instead +help: consider importing this trait instead | LL | use std::clone::Clone; | -LL | use std::prelude::v1::Clone; - | error[E0405]: cannot find trait `Iterator` in this scope --> $DIR/no-implicit-prelude-nested.rs:13:14 @@ -28,12 +26,10 @@ error[E0405]: cannot find trait `Iterator` in this scope LL | impl Iterator for Test {} | ^^^^^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this trait | LL | use std::iter::Iterator; | -LL | use std::prelude::v1::Iterator; - | error[E0405]: cannot find trait `ToString` in this scope --> $DIR/no-implicit-prelude-nested.rs:14:14 @@ -41,9 +37,7 @@ error[E0405]: cannot find trait `ToString` in this scope LL | impl ToString for Test {} | ^^^^^^^^ not found in this scope | -help: consider importing one of these items - | -LL | use std::prelude::v1::ToString; +help: consider importing this trait | LL | use std::string::ToString; | @@ -60,12 +54,10 @@ error[E0425]: cannot find function `drop` in this scope LL | drop(2) | ^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this function | LL | use std::mem::drop; | -LL | use std::prelude::v1::drop; - | error[E0405]: cannot find trait `Add` in this scope --> $DIR/no-implicit-prelude-nested.rs:23:10 @@ -84,12 +76,10 @@ error[E0404]: expected trait, found derive macro `Clone` LL | impl Clone for Test {} | ^^^^^ not a trait | -help: consider importing one of these items instead +help: consider importing this trait instead | LL | use std::clone::Clone; | -LL | use std::prelude::v1::Clone; - | error[E0405]: cannot find trait `Iterator` in this scope --> $DIR/no-implicit-prelude-nested.rs:25:10 @@ -97,12 +87,10 @@ error[E0405]: cannot find trait `Iterator` in this scope LL | impl Iterator for Test {} | ^^^^^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this trait | LL | use std::iter::Iterator; | -LL | use std::prelude::v1::Iterator; - | error[E0405]: cannot find trait `ToString` in this scope --> $DIR/no-implicit-prelude-nested.rs:26:10 @@ -110,9 +98,7 @@ error[E0405]: cannot find trait `ToString` in this scope LL | impl ToString for Test {} | ^^^^^^^^ not found in this scope | -help: consider importing one of these items - | -LL | use std::prelude::v1::ToString; +help: consider importing this trait | LL | use std::string::ToString; | @@ -129,12 +115,10 @@ error[E0425]: cannot find function `drop` in this scope LL | drop(2) | ^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this function | LL | use std::mem::drop; | -LL | use std::prelude::v1::drop; - | error[E0405]: cannot find trait `Add` in this scope --> $DIR/no-implicit-prelude-nested.rs:38:14 @@ -153,12 +137,10 @@ error[E0404]: expected trait, found derive macro `Clone` LL | impl Clone for Test {} | ^^^^^ not a trait | -help: consider importing one of these items instead +help: consider importing this trait instead | LL | use std::clone::Clone; | -LL | use std::prelude::v1::Clone; - | error[E0405]: cannot find trait `Iterator` in this scope --> $DIR/no-implicit-prelude-nested.rs:40:14 @@ -166,12 +148,10 @@ error[E0405]: cannot find trait `Iterator` in this scope LL | impl Iterator for Test {} | ^^^^^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this trait | LL | use std::iter::Iterator; | -LL | use std::prelude::v1::Iterator; - | error[E0405]: cannot find trait `ToString` in this scope --> $DIR/no-implicit-prelude-nested.rs:41:14 @@ -179,9 +159,7 @@ error[E0405]: cannot find trait `ToString` in this scope LL | impl ToString for Test {} | ^^^^^^^^ not found in this scope | -help: consider importing one of these items - | -LL | use std::prelude::v1::ToString; +help: consider importing this trait | LL | use std::string::ToString; | @@ -198,12 +176,10 @@ error[E0425]: cannot find function `drop` in this scope LL | drop(2) | ^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this function | LL | use std::mem::drop; | -LL | use std::prelude::v1::drop; - | error: aborting due to 18 previous errors diff --git a/src/test/ui/no-implicit-prelude.stderr b/src/test/ui/no-implicit-prelude.stderr index 9cda4f64c79..36a9b65b7d1 100644 --- a/src/test/ui/no-implicit-prelude.stderr +++ b/src/test/ui/no-implicit-prelude.stderr @@ -15,12 +15,10 @@ error[E0404]: expected trait, found derive macro `Clone` LL | impl Clone for Test {} | ^^^^^ not a trait | -help: consider importing one of these items instead +help: consider importing this trait instead | LL | use std::clone::Clone; | -LL | use std::prelude::v1::Clone; - | error[E0405]: cannot find trait `Iterator` in this scope --> $DIR/no-implicit-prelude.rs:12:6 @@ -28,12 +26,10 @@ error[E0405]: cannot find trait `Iterator` in this scope LL | impl Iterator for Test {} | ^^^^^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this trait | LL | use std::iter::Iterator; | -LL | use std::prelude::v1::Iterator; - | error[E0405]: cannot find trait `ToString` in this scope --> $DIR/no-implicit-prelude.rs:13:6 @@ -41,9 +37,7 @@ error[E0405]: cannot find trait `ToString` in this scope LL | impl ToString for Test {} | ^^^^^^^^ not found in this scope | -help: consider importing one of these items - | -LL | use std::prelude::v1::ToString; +help: consider importing this trait | LL | use std::string::ToString; | @@ -60,12 +54,10 @@ error[E0425]: cannot find function `drop` in this scope LL | drop(2) | ^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this function | LL | use std::mem::drop; | -LL | use std::prelude::v1::drop; - | error: aborting due to 6 previous errors diff --git a/src/test/ui/resolve/use_suggestion.stderr b/src/test/ui/resolve/use_suggestion.stderr index 2fd3d5dccd2..72dda940729 100644 --- a/src/test/ui/resolve/use_suggestion.stderr +++ b/src/test/ui/resolve/use_suggestion.stderr @@ -10,12 +10,10 @@ error[E0433]: failed to resolve: use of undeclared type or module `HashMap` LL | let x1 = HashMap::new(); | ^^^^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this struct | LL | use std::collections::HashMap; | -LL | use std::collections::hash_map::HashMap; - | error[E0412]: cannot find type `HashMap` in this scope --> $DIR/use_suggestion.rs:5:13 @@ -23,12 +21,10 @@ error[E0412]: cannot find type `HashMap` in this scope LL | let y1: HashMap; | ^^^^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this struct | LL | use std::collections::HashMap; | -LL | use std::collections::hash_map::HashMap; - | error[E0412]: cannot find type `GooMap` in this scope --> $DIR/use_suggestion.rs:6:13 diff --git a/src/test/ui/resolve/use_suggestion_placement.stderr b/src/test/ui/resolve/use_suggestion_placement.stderr index 9c337f515ad..3f91760fe21 100644 --- a/src/test/ui/resolve/use_suggestion_placement.stderr +++ b/src/test/ui/resolve/use_suggestion_placement.stderr @@ -26,12 +26,10 @@ error[E0412]: cannot find type `HashMap` in this scope LL | type Dict = HashMap; | ^^^^^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this struct | LL | use std::collections::HashMap; | -LL | use std::collections::hash_map::HashMap; - | error: aborting due to 3 previous errors From a8640cdf47b5424a1a194551f3e873e8d2726cb4 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 1 Jun 2020 15:34:45 +0100 Subject: [PATCH 15/20] improper_ctypes: add test for #66202 This commit adds a test of the improper ctypes lint, checking that return type are normalized bethat return types are normalized before being checked for FFI-safety, and that transparent newtype wrappers are FFI-safe if the type being wrapped is FFI-safe. Signed-off-by: David Wood --- src/test/ui/lint/lint-ctypes-66202.rs | 17 +++++++++++++ src/test/ui/lint/lint-ctypes-66202.stderr | 29 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/test/ui/lint/lint-ctypes-66202.rs create mode 100644 src/test/ui/lint/lint-ctypes-66202.stderr diff --git a/src/test/ui/lint/lint-ctypes-66202.rs b/src/test/ui/lint/lint-ctypes-66202.rs new file mode 100644 index 00000000000..df8170d8d96 --- /dev/null +++ b/src/test/ui/lint/lint-ctypes-66202.rs @@ -0,0 +1,17 @@ +#![deny(improper_ctypes)] + +// This test checks that return types are normalized before being checked for FFI-safety, and that +// transparent newtype wrappers are FFI-safe if the type being wrapped is FFI-safe. + +#[repr(transparent)] +pub struct W(T); + +extern "C" { + pub fn bare() -> (); + pub fn normalize() -> <() as ToOwned>::Owned; + //~^ ERROR uses type `()` + pub fn transparent() -> W<()>; + //~^ ERROR uses type `W<()>` +} + +fn main() {} diff --git a/src/test/ui/lint/lint-ctypes-66202.stderr b/src/test/ui/lint/lint-ctypes-66202.stderr new file mode 100644 index 00000000000..3268d4cefbf --- /dev/null +++ b/src/test/ui/lint/lint-ctypes-66202.stderr @@ -0,0 +1,29 @@ +error: `extern` block uses type `()`, which is not FFI-safe + --> $DIR/lint-ctypes-66202.rs:11:27 + | +LL | pub fn normalize() -> <() as ToOwned>::Owned; + | ^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | +note: the lint level is defined here + --> $DIR/lint-ctypes-66202.rs:1:9 + | +LL | #![deny(improper_ctypes)] + | ^^^^^^^^^^^^^^^ + = help: consider using a struct instead + = note: tuples have unspecified layout + +error: `extern` block uses type `W<()>`, which is not FFI-safe + --> $DIR/lint-ctypes-66202.rs:13:29 + | +LL | pub fn transparent() -> W<()>; + | ^^^^^ not FFI-safe + | + = note: composed only of `PhantomData` +note: the type is defined here + --> $DIR/lint-ctypes-66202.rs:7:1 + | +LL | pub struct W(T); + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 3e7aabb1b3ec9ad66c7a306cd956e880a1a51483 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 1 Jun 2020 15:41:36 +0100 Subject: [PATCH 16/20] lint: check for unit ret type after normalization This commit moves the check that skips unit return types to after where the return type has been normalized - therefore ensuring that FFI-safety lints are not emitted for types which normalize to unit. Signed-off-by: David Wood --- src/librustc_lint/types.rs | 31 +++++++++++++++-------- src/test/ui/lint/lint-ctypes-66202.rs | 1 - src/test/ui/lint/lint-ctypes-66202.stderr | 19 ++++---------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 703c2a7a443..b60867b3d2d 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -946,7 +946,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } } - fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>, is_static: bool) { + fn check_type_for_ffi_and_report_errors( + &mut self, + sp: Span, + ty: Ty<'tcx>, + is_static: bool, + is_return_type: bool, + ) { // We have to check for opaque types before `normalize_erasing_regions`, // which will replace opaque types with their underlying concrete type. if self.check_for_opaque_ty(sp, ty) { @@ -957,14 +963,21 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // it is only OK to use this function because extern fns cannot have // any generic types right now: let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); - // C doesn't really support passing arrays by value. - // The only way to pass an array by value is through a struct. - // So we first test that the top level isn't an array, - // and then recursively check the types inside. + + // C doesn't really support passing arrays by value - the only way to pass an array by value + // is through a struct. So, first test that the top level isn't an array, and then + // recursively check the types inside. if !is_static && self.check_for_array_ty(sp, ty) { return; } + // Don't report FFI errors for unit return types. This check exists here, and not in + // `check_foreign_fn` (where it would make more sense) so that normalization has definitely + // happened. + if is_return_type && ty.is_unit() { + return; + } + match self.check_type_for_ffi(&mut FxHashSet::default(), ty) { FfiResult::FfiSafe => {} FfiResult::FfiPhantom(ty) => { @@ -982,21 +995,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let sig = self.cx.tcx.erase_late_bound_regions(&sig); for (input_ty, input_hir) in sig.inputs().iter().zip(decl.inputs) { - self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false); + self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false, false); } if let hir::FnRetTy::Return(ref ret_hir) = decl.output { let ret_ty = sig.output(); - if !ret_ty.is_unit() { - self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false); - } + self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false, true); } } fn check_foreign_static(&mut self, id: hir::HirId, span: Span) { let def_id = self.cx.tcx.hir().local_def_id(id); let ty = self.cx.tcx.type_of(def_id); - self.check_type_for_ffi_and_report_errors(span, ty, true); + self.check_type_for_ffi_and_report_errors(span, ty, true, false); } } diff --git a/src/test/ui/lint/lint-ctypes-66202.rs b/src/test/ui/lint/lint-ctypes-66202.rs index df8170d8d96..3fe4560f44b 100644 --- a/src/test/ui/lint/lint-ctypes-66202.rs +++ b/src/test/ui/lint/lint-ctypes-66202.rs @@ -9,7 +9,6 @@ pub struct W(T); extern "C" { pub fn bare() -> (); pub fn normalize() -> <() as ToOwned>::Owned; - //~^ ERROR uses type `()` pub fn transparent() -> W<()>; //~^ ERROR uses type `W<()>` } diff --git a/src/test/ui/lint/lint-ctypes-66202.stderr b/src/test/ui/lint/lint-ctypes-66202.stderr index 3268d4cefbf..759c77deadc 100644 --- a/src/test/ui/lint/lint-ctypes-66202.stderr +++ b/src/test/ui/lint/lint-ctypes-66202.stderr @@ -1,23 +1,14 @@ -error: `extern` block uses type `()`, which is not FFI-safe - --> $DIR/lint-ctypes-66202.rs:11:27 +error: `extern` block uses type `W<()>`, which is not FFI-safe + --> $DIR/lint-ctypes-66202.rs:12:29 | -LL | pub fn normalize() -> <() as ToOwned>::Owned; - | ^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | pub fn transparent() -> W<()>; + | ^^^^^ not FFI-safe | note: the lint level is defined here --> $DIR/lint-ctypes-66202.rs:1:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ - = help: consider using a struct instead - = note: tuples have unspecified layout - -error: `extern` block uses type `W<()>`, which is not FFI-safe - --> $DIR/lint-ctypes-66202.rs:13:29 - | -LL | pub fn transparent() -> W<()>; - | ^^^^^ not FFI-safe - | = note: composed only of `PhantomData` note: the type is defined here --> $DIR/lint-ctypes-66202.rs:7:1 @@ -25,5 +16,5 @@ note: the type is defined here LL | pub struct W(T); | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error From d4d3d7de68d331829b5dcd08be3d4aec1a7a7f2b Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 1 Jun 2020 17:00:58 +0100 Subject: [PATCH 17/20] lint: transitive FFI-safety for transparent types This commit ensures that if a `repr(transparent)` newtype's only non-zero-sized field is FFI-safe then the newtype is also FFI-safe. Previously, ZSTs were ignored for the purposes of linting FFI-safety in transparent structs - thus, only the single non-ZST would be checked for FFI-safety. However, if the non-zero-sized field is a generic parameter, and is substituted for a ZST, then the type would be considered FFI-unsafe (as when every field is thought to be zero-sized, the type is considered to be "composed only of `PhantomData`" which is FFI-unsafe). In this commit, for transparent structs, the non-zero-sized field is identified (before any substitutions are applied, necessarily) and then that field's type (now with substitutions) is checked for FFI-safety (where previously it would have been skipped for being zero-sized in this case). To handle the case where the non-zero-sized field is a generic parameter, which is substituted for `()` (a ZST), and is being used as a return type - the `FfiUnsafe` result (previously `FfiPhantom`) is caught and silenced. Signed-off-by: David Wood --- src/librustc_lint/types.rs | 69 +++++++++++++---------- src/librustc_middle/ty/mod.rs | 23 ++++++++ src/librustc_middle/ty/sty.rs | 5 ++ src/test/ui/lint/lint-ctypes-66202.rs | 3 +- src/test/ui/lint/lint-ctypes-66202.stderr | 20 ------- 5 files changed, 69 insertions(+), 51 deletions(-) delete mode 100644 src/test/ui/lint/lint-ctypes-66202.stderr diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index b60867b3d2d..cdb0eda645a 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -6,7 +6,6 @@ use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_hir::def_id::DefId; use rustc_hir::{is_range_literal, ExprKind, Node}; use rustc_index::vec::Idx; use rustc_middle::mir::interpret::{sign_extend, truncate}; @@ -511,10 +510,6 @@ enum FfiResult<'tcx> { FfiUnsafe { ty: Ty<'tcx>, reason: &'static str, help: Option<&'static str> }, } -fn is_zst<'tcx>(tcx: TyCtxt<'tcx>, did: DefId, ty: Ty<'tcx>) -> bool { - tcx.layout_of(tcx.param_env(did).and(ty)).map(|layout| layout.is_zst()).unwrap_or(false) -} - fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { match ty.kind { ty::FnPtr(_) => true, @@ -523,7 +518,7 @@ fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { for field in field_def.all_fields() { let field_ty = tcx.normalize_erasing_regions(ParamEnv::reveal_all(), field.ty(tcx, substs)); - if is_zst(tcx, field.did, field_ty) { + if field_ty.is_zst(tcx, field.did) { continue; } @@ -653,32 +648,43 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { }; } - // We can't completely trust repr(C) and repr(transparent) markings; - // make sure the fields are actually safe. - let mut all_phantom = true; - for field in &def.non_enum_variant().fields { - let field_ty = cx.normalize_erasing_regions( - ParamEnv::reveal_all(), - field.ty(cx, substs), - ); - // repr(transparent) types are allowed to have arbitrary ZSTs, not just - // PhantomData -- skip checking all ZST fields - if def.repr.transparent() && is_zst(cx, field.did, field_ty) { - continue; + if def.repr.transparent() { + // Can assume that only one field is not a ZST, so only check + // that field's type for FFI-safety. + if let Some(field) = + def.transparent_newtype_field(cx, self.cx.param_env) + { + let field_ty = cx.normalize_erasing_regions( + self.cx.param_env, + field.ty(cx, substs), + ); + self.check_type_for_ffi(cache, field_ty) + } else { + FfiSafe } - let r = self.check_type_for_ffi(cache, field_ty); - match r { - FfiSafe => { - all_phantom = false; - } - FfiPhantom(..) => {} - FfiUnsafe { .. } => { - return r; + } else { + // We can't completely trust repr(C) markings; make sure the fields are + // actually safe. + let mut all_phantom = true; + for field in &def.non_enum_variant().fields { + let field_ty = cx.normalize_erasing_regions( + self.cx.param_env, + field.ty(cx, substs), + ); + let r = self.check_type_for_ffi(cache, field_ty); + match r { + FfiSafe => { + all_phantom = false; + } + FfiPhantom(..) => {} + FfiUnsafe { .. } => { + return r; + } } } - } - if all_phantom { FfiPhantom(ty) } else { FfiSafe } + if all_phantom { FfiPhantom(ty) } else { FfiSafe } + } } AdtKind::Union => { if !def.repr.c() && !def.repr.transparent() { @@ -708,7 +714,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ); // repr(transparent) types are allowed to have arbitrary ZSTs, not just // PhantomData -- skip checking all ZST fields. - if def.repr.transparent() && is_zst(cx, field.did, field_ty) { + if def.repr.transparent() && field_ty.is_zst(cx, field.did) { continue; } let r = self.check_type_for_ffi(cache, field_ty); @@ -774,7 +780,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ); // repr(transparent) types are allowed to have arbitrary ZSTs, not // just PhantomData -- skip checking all ZST fields. - if def.repr.transparent() && is_zst(cx, field.did, field_ty) { + if def.repr.transparent() && field_ty.is_zst(cx, field.did) { continue; } let r = self.check_type_for_ffi(cache, field_ty); @@ -983,6 +989,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { FfiResult::FfiPhantom(ty) => { self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None); } + // If `ty` is a `repr(transparent)` newtype, and the non-zero-sized type is a generic + // argument, which after substitution, is `()`, then this branch can be hit. + FfiResult::FfiUnsafe { ty, .. } if is_return_type && ty.is_unit() => return, FfiResult::FfiUnsafe { ty, reason, help } => { self.emit_ffi_unsafe_type_lint(ty, sp, reason, help); } diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index ffbe3a40297..caa1b4cb375 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -2390,6 +2390,29 @@ impl<'tcx> AdtDef { pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] { tcx.adt_sized_constraint(self.did).0 } + + /// `repr(transparent)` structs can have a single non-ZST field, this function returns that + /// field. + pub fn transparent_newtype_field( + &self, + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + ) -> Option<&FieldDef> { + assert!(self.is_struct() && self.repr.transparent()); + + for field in &self.non_enum_variant().fields { + let field_ty = tcx.normalize_erasing_regions( + param_env, + field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.did)), + ); + + if !field_ty.is_zst(tcx, self.did) { + return Some(field); + } + } + + None + } } impl<'tcx> FieldDef { diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index 5d4c2a54267..7550be39d4a 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -2186,6 +2186,11 @@ impl<'tcx> TyS<'tcx> { } } } + + /// Is this a zero-sized type? + pub fn is_zst(&'tcx self, tcx: TyCtxt<'tcx>, did: DefId) -> bool { + tcx.layout_of(tcx.param_env(did).and(self)).map(|layout| layout.is_zst()).unwrap_or(false) + } } /// Typed constant value. diff --git a/src/test/ui/lint/lint-ctypes-66202.rs b/src/test/ui/lint/lint-ctypes-66202.rs index 3fe4560f44b..ebab41d143e 100644 --- a/src/test/ui/lint/lint-ctypes-66202.rs +++ b/src/test/ui/lint/lint-ctypes-66202.rs @@ -1,3 +1,5 @@ +// check-pass + #![deny(improper_ctypes)] // This test checks that return types are normalized before being checked for FFI-safety, and that @@ -10,7 +12,6 @@ extern "C" { pub fn bare() -> (); pub fn normalize() -> <() as ToOwned>::Owned; pub fn transparent() -> W<()>; - //~^ ERROR uses type `W<()>` } fn main() {} diff --git a/src/test/ui/lint/lint-ctypes-66202.stderr b/src/test/ui/lint/lint-ctypes-66202.stderr deleted file mode 100644 index 759c77deadc..00000000000 --- a/src/test/ui/lint/lint-ctypes-66202.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: `extern` block uses type `W<()>`, which is not FFI-safe - --> $DIR/lint-ctypes-66202.rs:12:29 - | -LL | pub fn transparent() -> W<()>; - | ^^^^^ not FFI-safe - | -note: the lint level is defined here - --> $DIR/lint-ctypes-66202.rs:1:9 - | -LL | #![deny(improper_ctypes)] - | ^^^^^^^^^^^^^^^ - = note: composed only of `PhantomData` -note: the type is defined here - --> $DIR/lint-ctypes-66202.rs:7:1 - | -LL | pub struct W(T); - | ^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - From e237e0280b301457e5cc4bf6d559e91373a17d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Tue, 9 Jun 2020 23:57:16 +0200 Subject: [PATCH 18/20] Reoder order in which MinGW libs are linked --- src/librustc_target/spec/windows_gnu_base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_target/spec/windows_gnu_base.rs b/src/librustc_target/spec/windows_gnu_base.rs index f556bf03f02..744f26239ca 100644 --- a/src/librustc_target/spec/windows_gnu_base.rs +++ b/src/librustc_target/spec/windows_gnu_base.rs @@ -20,9 +20,9 @@ pub fn opts() -> TargetOptions { late_link_args.insert( LinkerFlavor::Gcc, vec![ + "-lmsvcrt".to_string(), "-lmingwex".to_string(), "-lmingw32".to_string(), - "-lmsvcrt".to_string(), // mingw's msvcrt is a weird hybrid import library and static library. // And it seems that the linker fails to use import symbols from msvcrt // that are required from functions in msvcrt in certain cases. For example From e0ec3d5dc6714007725089a3c86e245ebeffe08e Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 9 Jun 2020 18:01:58 -0400 Subject: [PATCH 19/20] fix URLs, include ARM --- triagebot.toml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 3a52cda81c9..ccd34e8afd6 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -20,7 +20,7 @@ Hey LLVM ICE-breakers! This bug has been identified as a good [instructions] for tackling these sorts of bugs. Maybe take a look? Thanks! <3 -[instructions]: https://rustc-dev-guide.rust-lang.org/ice-breaker/llvm.html +[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/llvm.html """ label = "ICEBreaker-LLVM" @@ -32,7 +32,7 @@ Hey Cleanup Crew ICE-breakers! This bug has been identified as a good [instructions] for tackling these sorts of bugs. Maybe take a look? Thanks! <3 -[instructions]: https://rustc-dev-guide.rust-lang.org/ice-breaker/cleanup-crew.html +[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/cleanup-crew.html """ label = "ICEBreaker-Cleanup-Crew" @@ -46,6 +46,16 @@ Thanks! <3 """ label = "O-windows" +[ping.arm] +message = """\ +Hey ARM Group! This bug has been identified as a good "ARM candidate". +In case it's useful, here are some [instructions] for tackling these sorts of +bugs. Maybe take a look? +Thanks! <3 +[instructions]: https://rust-lang.github.io/rustc-guide/notification-groups/arm.html +""" +label = "O-ARM" + [prioritize] label = "I-prioritize" prioritize_on = ["regression-from-stable-to-stable", "regression-from-stable-to-beta", "regression-from-stable-to-nightly"] From a01485c0da225f1565ff5ef3e12964b629269cea Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 9 Jun 2020 21:19:26 -0300 Subject: [PATCH 20/20] Fix rustc-dev-guide url --- triagebot.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index ccd34e8afd6..0895bafb4d1 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -42,7 +42,7 @@ Hey Windows Group! This bug has been identified as a good "Windows candidate". In case it's useful, here are some [instructions] for tackling these sorts of bugs. Maybe take a look? Thanks! <3 -[instructions]: https://rust-lang.github.io/rustc-guide/notification-groups/windows.html +[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/windows.html """ label = "O-windows" @@ -52,7 +52,7 @@ Hey ARM Group! This bug has been identified as a good "ARM candidate". In case it's useful, here are some [instructions] for tackling these sorts of bugs. Maybe take a look? Thanks! <3 -[instructions]: https://rust-lang.github.io/rustc-guide/notification-groups/arm.html +[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/arm.html """ label = "O-ARM"