diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 7577217401810..bad8600905e3e 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::{ }; use rustc_middle::util::Providers; use rustc_session::config::CrateType; +use rustc_session::cstore::CrateDepKind; use rustc_span::Span; use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{Arch, Os, TlsModel}; @@ -434,6 +435,14 @@ fn upstream_monomorphizations_provider( let async_drop_in_place_fn_def_id = tcx.lang_items().async_drop_in_place_fn(); for &cnum in cnums.iter() { + // It should be possible to compile to build a crate against a conditional dependency then + // later link that crate without the conditional dependency, so we cannot use exported + // generics from conditional dependencies. + // https://github.com/rust-lang/rust/issues/159682 + if tcx.crate_dep_kind(cnum) == CrateDepKind::Conditional { + continue; + } + for (exported_symbol, _) in tcx.exported_generic_symbols(cnum).iter() { let (def_id, args) = match *exported_symbol { ExportedSymbol::Generic(def_id, args) => (def_id, args), diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 156dfc4fc1e69..004d1df069d6e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -338,18 +338,6 @@ fn maybe_evaluate_root_goal_with_higher_recursion_limit( Ok(goal_evaluation) => goal_evaluation.goal.predicate, }; - // Some goals no longer overflow after the stalled infers are resolved. - // Thus we don't have to rerun eagerly here. - let has_stalled_infers = match predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Projection(projection)) => { - projection.projection_term.has_non_region_infer() - } - _ => predicate.has_non_region_infer(), - }; - if has_stalled_infers { - return; - } - let rerun_result = delegate.commit_if_ok(|| { let rerun_result = EvalCtxt::enter_root(delegate, delegate.cx().recursion_limit() * 2, span, |ecx| { @@ -397,19 +385,6 @@ fn maybe_evaluate_root_goal_for_proof_tree_with_higher_recursion_limit( Ok(_) => {} } - // Some goals no longer overflow after the stalled infers are resolved. - // Thus we don't have to rerun eagerly here. - let predicate: I::Predicate = goal_evaluation.uncanonicalized_goal.predicate; - let has_stalled_infers = match predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Projection(projection)) => { - projection.projection_term.has_non_region_infer() - } - _ => predicate.has_non_region_infer(), - }; - if has_stalled_infers { - return; - } - let rerun_result = delegate.commit_if_ok(|| { let (new_result, new_goal_evaluation) = evaluate_root_goal_for_proof_tree( delegate, @@ -426,6 +401,7 @@ fn maybe_evaluate_root_goal_for_proof_tree_with_higher_recursion_limit( } }); if let Ok(rerun_result) = rerun_result { + let predicate: I::Predicate = goal_evaluation.uncanonicalized_goal.predicate; delegate.cx().emit_next_solver_overflow_fcw(predicate, span); *initial_result = rerun_result; } diff --git a/tests/ui/fn/fn-ptr-pattern.rs b/tests/ui/fn/fn-ptr-pattern.rs index 017356d561915..9bf759af19af7 100644 --- a/tests/ui/fn/fn-ptr-pattern.rs +++ b/tests/ui/fn/fn-ptr-pattern.rs @@ -1,26 +1,77 @@ -fn patterns( - pat1: fn(true: bool), +fn allowed( + data: &str, + f1: fn(msg: String), + f2: fn(_: String), + f3: fn(String, msg: String), + f4: fn(msg: String, String), + f5: fn(duplicate_name: bool, duplicate_name: bool), +) { } + + +// Patterns are semantically rejected +fn semantics( + pat1: fn(1..3: bool), //~^ ERROR patterns aren't allowed in function pointer types - pat2: fn(1..3: bool), + pat2: fn((x, y): (bool, bool)), //~^ ERROR patterns aren't allowed in function pointer types - pat3: fn((x, y): (bool, bool)), + pat3: fn(Thing { a, b }: Thing), + //~^ ERROR patterns aren't allowed in function pointer types + pat4: fn(NoThing { a, b }: NoThing), + //~^ ERROR patterns aren't allowed in function pointer types + //~| ERROR cannot find type `NoThing` in this scope + pat5: fn((((((x))))): bool), //~^ ERROR patterns aren't allowed in function pointer types - pat4: fn(self), + + self1: fn(self), //~^ ERROR `self` parameter is only allowed in associated functions - pat5: fn(self, self), + self2: fn(self, self), //~^ ERROR `self` parameter is only allowed in associated functions //~| ERROR unexpected `self` parameter in function - pat6: fn(bool, self), + self3: fn(bool, self), //~^ ERROR unexpected `self` parameter in function - pat7: fn(Thing { a, b }: Thing), + + restricted_pat1: fn(mut x: ()), //~^ ERROR patterns aren't allowed in function pointer types - pat8: fn(NoThing { a, b }: NoThing), + restricted_pat2: fn(&x: ()), //~^ ERROR patterns aren't allowed in function pointer types - //~| ERROR cannot find type `NoThing` in this scope - pat9: fn((((((x))))): bool), + restricted_pat3: fn(&&x: ()), + //~^ ERROR patterns aren't allowed in function pointer types + restricted_pat4: fn(false: ()), + //~^ ERROR patterns aren't allowed in function pointer types + restricted_pat5: fn(&_: ()), + //~^ ERROR patterns aren't allowed in function pointer types + restricted_pat6: fn(&true: ()), //~^ ERROR patterns aren't allowed in function pointer types ) { } +// Patterns are also syntactically rejected, but restricted patterns are not +#[cfg(false)] +fn syntax( + pat1: fn(1..3: bool), + //~^ ERROR patterns aren't allowed in function pointer types + pat2: fn((x, y): (bool, bool)), + //~^ ERROR patterns aren't allowed in function pointer types + pat3: fn(Thing { a, b }: Thing), + //~^ ERROR patterns aren't allowed in function pointer types + pat4: fn(NoThing { a, b }: NoThing), + //~^ ERROR patterns aren't allowed in function pointer types + pat5: fn((((((x))))): bool), + //~^ ERROR patterns aren't allowed in function pointer types + + self1: fn(self), + self2: fn(self, self), + //~^ ERROR unexpected `self` parameter in function + self3: fn(bool, self), + //~^ ERROR unexpected `self` parameter in function + + restricted_pat1: fn(mut x: ()), + restricted_pat2: fn(&x: ()), + restricted_pat3: fn(&&x: ()), + restricted_pat4: fn(false: ()), + restricted_pat5: fn(&_: ()), + restricted_pat6: fn(&true: ()), +) { } + struct Thing { a: bool, b: bool } fn main() { diff --git a/tests/ui/fn/fn-ptr-pattern.stderr b/tests/ui/fn/fn-ptr-pattern.stderr index 99d890cbbc9dc..f9baa6863b4c7 100644 --- a/tests/ui/fn/fn-ptr-pattern.stderr +++ b/tests/ui/fn/fn-ptr-pattern.stderr @@ -1,101 +1,203 @@ error[E0642]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:4:14 + --> $DIR/fn-ptr-pattern.rs:13:14 | -LL | pat2: fn(1..3: bool), +LL | pat1: fn(1..3: bool), | ^^^^ | help: give this argument a name or use an underscore to ignore it | -LL - pat2: fn(1..3: bool), -LL + pat2: fn(_: bool), +LL - pat1: fn(1..3: bool), +LL + pat1: fn(_: bool), | error[E0642]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:6:14 + --> $DIR/fn-ptr-pattern.rs:15:14 | -LL | pat3: fn((x, y): (bool, bool)), +LL | pat2: fn((x, y): (bool, bool)), | ^^^^^^ | help: give this argument a name or use an underscore to ignore it | -LL - pat3: fn((x, y): (bool, bool)), -LL + pat3: fn(_: (bool, bool)), +LL - pat2: fn((x, y): (bool, bool)), +LL + pat2: fn(_: (bool, bool)), + | + +error[E0642]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:17:14 + | +LL | pat3: fn(Thing { a, b }: Thing), + | ^^^^^^^^^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat3: fn(Thing { a, b }: Thing), +LL + pat3: fn(_: Thing), + | + +error[E0642]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:19:14 + | +LL | pat4: fn(NoThing { a, b }: NoThing), + | ^^^^^^^^^^^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat4: fn(NoThing { a, b }: NoThing), +LL + pat4: fn(_: NoThing), + | + +error[E0642]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:22:14 + | +LL | pat5: fn((((((x))))): bool), + | ^^^^^^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat5: fn((((((x))))): bool), +LL + pat5: fn(_: bool), | error: unexpected `self` parameter in function - --> $DIR/fn-ptr-pattern.rs:10:20 + --> $DIR/fn-ptr-pattern.rs:27:21 | -LL | pat5: fn(self, self), - | ^^^^ must be the first parameter of an associated function +LL | self2: fn(self, self), + | ^^^^ must be the first parameter of an associated function error: unexpected `self` parameter in function - --> $DIR/fn-ptr-pattern.rs:13:20 + --> $DIR/fn-ptr-pattern.rs:30:21 | -LL | pat6: fn(bool, self), - | ^^^^ must be the first parameter of an associated function +LL | self3: fn(bool, self), + | ^^^^ must be the first parameter of an associated function error[E0642]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:15:14 + --> $DIR/fn-ptr-pattern.rs:50:14 + | +LL | pat1: fn(1..3: bool), + | ^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat1: fn(1..3: bool), +LL + pat1: fn(_: bool), + | + +error[E0642]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:52:14 + | +LL | pat2: fn((x, y): (bool, bool)), + | ^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat2: fn((x, y): (bool, bool)), +LL + pat2: fn(_: (bool, bool)), + | + +error[E0642]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:54:14 | -LL | pat7: fn(Thing { a, b }: Thing), +LL | pat3: fn(Thing { a, b }: Thing), | ^^^^^^^^^^^^^^ | help: give this argument a name or use an underscore to ignore it | -LL - pat7: fn(Thing { a, b }: Thing), -LL + pat7: fn(_: Thing), +LL - pat3: fn(Thing { a, b }: Thing), +LL + pat3: fn(_: Thing), | error[E0642]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:17:14 + --> $DIR/fn-ptr-pattern.rs:56:14 | -LL | pat8: fn(NoThing { a, b }: NoThing), +LL | pat4: fn(NoThing { a, b }: NoThing), | ^^^^^^^^^^^^^^^^ | help: give this argument a name or use an underscore to ignore it | -LL - pat8: fn(NoThing { a, b }: NoThing), -LL + pat8: fn(_: NoThing), +LL - pat4: fn(NoThing { a, b }: NoThing), +LL + pat4: fn(_: NoThing), | error[E0642]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:20:14 + --> $DIR/fn-ptr-pattern.rs:58:14 | -LL | pat9: fn((((((x))))): bool), +LL | pat5: fn((((((x))))): bool), | ^^^^^^^^^^^ | help: give this argument a name or use an underscore to ignore it | -LL - pat9: fn((((((x))))): bool), -LL + pat9: fn(_: bool), +LL - pat5: fn((((((x))))): bool), +LL + pat5: fn(_: bool), | -error[E0561]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:2:14 +error: unexpected `self` parameter in function + --> $DIR/fn-ptr-pattern.rs:62:21 | -LL | pat1: fn(true: bool), - | ^^^^ +LL | self2: fn(self, self), + | ^^^^ must be the first parameter of an associated function + +error: unexpected `self` parameter in function + --> $DIR/fn-ptr-pattern.rs:64:21 + | +LL | self3: fn(bool, self), + | ^^^^ must be the first parameter of an associated function error: `self` parameter is only allowed in associated functions - --> $DIR/fn-ptr-pattern.rs:8:14 + --> $DIR/fn-ptr-pattern.rs:25:15 | -LL | pat4: fn(self), - | ^^^^ not semantically valid as function parameter +LL | self1: fn(self), + | ^^^^ not semantically valid as function parameter | = note: associated functions are those in `impl` or `trait` definitions error: `self` parameter is only allowed in associated functions - --> $DIR/fn-ptr-pattern.rs:10:14 + --> $DIR/fn-ptr-pattern.rs:27:15 | -LL | pat5: fn(self, self), - | ^^^^ not semantically valid as function parameter +LL | self2: fn(self, self), + | ^^^^ not semantically valid as function parameter | = note: associated functions are those in `impl` or `trait` definitions +error[E0561]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:33:25 + | +LL | restricted_pat1: fn(mut x: ()), + | ^^^^^ + +error[E0561]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:35:25 + | +LL | restricted_pat2: fn(&x: ()), + | ^^ + +error[E0561]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:37:25 + | +LL | restricted_pat3: fn(&&x: ()), + | ^^^ + +error[E0561]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:39:25 + | +LL | restricted_pat4: fn(false: ()), + | ^^^^^ + +error[E0561]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:41:25 + | +LL | restricted_pat5: fn(&_: ()), + | ^^ + +error[E0561]: patterns aren't allowed in function pointer types + --> $DIR/fn-ptr-pattern.rs:43:25 + | +LL | restricted_pat6: fn(&true: ()), + | ^^^^^ + error[E0425]: cannot find type `NoThing` in this scope - --> $DIR/fn-ptr-pattern.rs:17:32 + --> $DIR/fn-ptr-pattern.rs:19:32 | -LL | pat8: fn(NoThing { a, b }: NoThing), +LL | pat4: fn(NoThing { a, b }: NoThing), | ^^^^^^^ ... LL | struct Thing { a: bool, b: bool } @@ -103,11 +205,11 @@ LL | struct Thing { a: bool, b: bool } | help: a struct with a similar name exists | -LL - pat8: fn(NoThing { a, b }: NoThing), -LL + pat8: fn(NoThing { a, b }: Thing), +LL - pat4: fn(NoThing { a, b }: NoThing), +LL + pat4: fn(NoThing { a, b }: Thing), | -error: aborting due to 11 previous errors +error: aborting due to 23 previous errors Some errors have detailed explanations: E0425, E0561, E0642. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/traits/next-solver/overflow-discards-constraints.rs b/tests/ui/traits/next-solver/overflow-discards-constraints.rs new file mode 100644 index 0000000000000..a5432f40a8659 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow-discards-constraints.rs @@ -0,0 +1,75 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Previously we didn't rerun the goal with doubled recursion limit if the goal contained ty vars. +// This is to avoid futile evaluation. However, sometimes the type inference progress relies on +// successful trait solving response. If we don't evaluate with higher recursion limit, the type +// inference would fail eventually. +// +// See the `recursion_depth_exceeding_limit` FCW for why we need the doubled recursion limit. + +// Setting it to 12 would make it compile. +#![recursion_limit = "6"] + +trait Trait {} + +struct W1(T); +struct W2(T); +struct W3(T); +struct W4(T); +struct W5(T); +struct W6(T); +struct W7(T); + + +impl Trait for () + where + W1: Trait, +{} + +impl Trait for W1 +where + W2: Trait, +{} + +impl Trait for W2 +where + W3: Trait, +{} + +impl Trait for W3 +where + W4: Trait, +{} + +impl Trait for W4 +where + W5: Trait, +{} + +impl Trait for W5 +where + W6: Trait, +{} + +impl Trait for W6 +where + W7: Trait, +{} + +impl Trait for W7 {} + +fn foo() + where + (): Trait, +{ +} + +fn main() { + foo(); // register a `(): Trait` obligation + //~^ WARN: overflow evaluating the requirement `(): Trait<_>` [recursion_depth_exceeding_limit] + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~| WARN: overflow evaluating the requirement `(): Trait` [recursion_depth_exceeding_limit] + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +} diff --git a/tests/ui/traits/next-solver/overflow-discards-constraints.stderr b/tests/ui/traits/next-solver/overflow-discards-constraints.stderr new file mode 100644 index 0000000000000..5705b0a97e58d --- /dev/null +++ b/tests/ui/traits/next-solver/overflow-discards-constraints.stderr @@ -0,0 +1,27 @@ +warning: overflow evaluating the requirement `(): Trait<_>` + --> $DIR/overflow-discards-constraints.rs:69:5 + | +LL | foo(); // register a `(): Trait` obligation + | ^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "12"]` attribute to your crate (`overflow_discards_constraints`) + = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved + = note: this lint is attached to the whole crate and can't be disabled on a per-function basis + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #159228 + = note: `#[warn(recursion_depth_exceeding_limit)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: overflow evaluating the requirement `(): Trait` + --> $DIR/overflow-discards-constraints.rs:69:5 + | +LL | foo(); // register a `(): Trait` obligation + | ^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "12"]` attribute to your crate (`overflow_discards_constraints`) + = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved + = note: this lint is attached to the whole crate and can't be disabled on a per-function basis + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #159228 + +warning: 2 warnings emitted +