Skip to content

Commit 1db9c06

Browse files
committed
Auto merge of rust-lang#109453 - matthiaskrgr:rollup-odn02wu, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#96391 (Windows: make `Command` prefer non-verbatim paths) - rust-lang#108164 (Drop all messages in bounded channel when destroying the last receiver) - rust-lang#108729 (fix: modify the condition that `resolve_imports` stops) - rust-lang#109336 (Constrain const vars to error if const types are mismatched) - rust-lang#109403 (Avoid ICE of attempt to add with overflow in emitter) - rust-lang#109415 (Refactor `handle_missing_lit`.) - rust-lang#109441 (Only implement Fn* traits for extern "Rust" safe function pointers and items) - rust-lang#109446 (Do not suggest bounds restrictions for synthesized RPITITs) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 77d50a8 + 94d2028 commit 1db9c06

File tree

27 files changed

+597
-139
lines changed

27 files changed

+597
-139
lines changed

compiler/rustc_errors/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ impl CodeSuggestion {
331331
});
332332
buf.push_str(&part.snippet);
333333
let cur_hi = sm.lookup_char_pos(part.span.hi());
334-
if cur_hi.line == cur_lo.line {
334+
if cur_hi.line == cur_lo.line && !part.snippet.is_empty() {
335335
// Account for the difference between the width of the current code and the
336336
// snippet being suggested, so that the *later* suggestions are correctly
337337
// aligned on the screen.

compiler/rustc_infer/src/infer/combine.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,19 @@ impl<'tcx> InferCtxt<'tcx> {
189189
// the expected const's type. Specifically, we don't want const infer vars
190190
// to do any type shapeshifting before and after resolution.
191191
if let Err(guar) = compatible_types {
192-
return Ok(self.tcx.const_error_with_guaranteed(
193-
if relation.a_is_expected() { a.ty() } else { b.ty() },
194-
guar,
195-
));
192+
// HACK: equating both sides with `[const error]` eagerly prevents us
193+
// from leaving unconstrained inference vars during things like impl
194+
// matching in the solver.
195+
let a_error = self.tcx.const_error_with_guaranteed(a.ty(), guar);
196+
if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() {
197+
return self.unify_const_variable(vid, a_error);
198+
}
199+
let b_error = self.tcx.const_error_with_guaranteed(b.ty(), guar);
200+
if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() {
201+
return self.unify_const_variable(vid, b_error);
202+
}
203+
204+
return Ok(if relation.a_is_expected() { a_error } else { b_error });
196205
}
197206

198207
match (a.kind(), b.kind()) {

compiler/rustc_middle/src/ty/sty.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_macros::HashStable;
2323
use rustc_span::symbol::{kw, sym, Symbol};
2424
use rustc_span::Span;
2525
use rustc_target::abi::VariantIdx;
26-
use rustc_target::spec::abi;
26+
use rustc_target::spec::abi::{self, Abi};
2727
use std::borrow::Cow;
2828
use std::cmp::Ordering;
2929
use std::fmt;
@@ -1403,6 +1403,18 @@ impl<'tcx> PolyFnSig<'tcx> {
14031403
pub fn abi(&self) -> abi::Abi {
14041404
self.skip_binder().abi
14051405
}
1406+
1407+
pub fn is_fn_trait_compatible(&self) -> bool {
1408+
matches!(
1409+
self.skip_binder(),
1410+
ty::FnSig {
1411+
unsafety: rustc_hir::Unsafety::Normal,
1412+
abi: Abi::Rust,
1413+
c_variadic: false,
1414+
..
1415+
}
1416+
)
1417+
}
14061418
}
14071419

14081420
pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>;

compiler/rustc_parse/src/parser/expr.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -1843,20 +1843,14 @@ impl<'a> Parser<'a> {
18431843
&mut self,
18441844
mk_lit_char: impl FnOnce(Symbol, Span) -> L,
18451845
) -> PResult<'a, L> {
1846-
if let token::Interpolated(inner) = &self.token.kind {
1847-
let expr = match inner.as_ref() {
1848-
token::NtExpr(expr) => Some(expr),
1849-
token::NtLiteral(expr) => Some(expr),
1850-
_ => None,
1851-
};
1852-
if let Some(expr) = expr {
1853-
if matches!(expr.kind, ExprKind::Err) {
1854-
let mut err = errors::InvalidInterpolatedExpression { span: self.token.span }
1855-
.into_diagnostic(&self.sess.span_diagnostic);
1856-
err.downgrade_to_delayed_bug();
1857-
return Err(err);
1858-
}
1859-
}
1846+
if let token::Interpolated(nt) = &self.token.kind
1847+
&& let token::NtExpr(e) | token::NtLiteral(e) = &**nt
1848+
&& matches!(e.kind, ExprKind::Err)
1849+
{
1850+
let mut err = errors::InvalidInterpolatedExpression { span: self.token.span }
1851+
.into_diagnostic(&self.sess.span_diagnostic);
1852+
err.downgrade_to_delayed_bug();
1853+
return Err(err);
18601854
}
18611855
let token = self.token.clone();
18621856
let err = |self_: &Self| {

compiler/rustc_resolve/src/imports.rs

+23-15
Original file line numberDiff line numberDiff line change
@@ -423,13 +423,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
423423
/// Resolves all imports for the crate. This method performs the fixed-
424424
/// point iteration.
425425
pub(crate) fn resolve_imports(&mut self) {
426-
let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1;
427-
while self.indeterminate_imports.len() < prev_num_indeterminates {
428-
prev_num_indeterminates = self.indeterminate_imports.len();
426+
let mut prev_indeterminate_count = usize::MAX;
427+
let mut indeterminate_count = self.indeterminate_imports.len() * 3;
428+
while indeterminate_count < prev_indeterminate_count {
429+
prev_indeterminate_count = indeterminate_count;
430+
indeterminate_count = 0;
429431
for import in mem::take(&mut self.indeterminate_imports) {
430-
match self.resolve_import(&import) {
431-
true => self.determined_imports.push(import),
432-
false => self.indeterminate_imports.push(import),
432+
let import_indeterminate_count = self.resolve_import(&import);
433+
indeterminate_count += import_indeterminate_count;
434+
match import_indeterminate_count {
435+
0 => self.determined_imports.push(import),
436+
_ => self.indeterminate_imports.push(import),
433437
}
434438
}
435439
}
@@ -581,9 +585,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
581585
diag.emit();
582586
}
583587

584-
/// Attempts to resolve the given import, returning true if its resolution is determined.
585-
/// If successful, the resolved bindings are written into the module.
586-
fn resolve_import(&mut self, import: &'a Import<'a>) -> bool {
588+
/// Attempts to resolve the given import, returning:
589+
/// - `0` means its resolution is determined.
590+
/// - Other values mean that indeterminate exists under certain namespaces.
591+
///
592+
/// Meanwhile, if resolve successful, the resolved bindings are written
593+
/// into the module.
594+
fn resolve_import(&mut self, import: &'a Import<'a>) -> usize {
587595
debug!(
588596
"(resolving import for module) resolving import `{}::...` in `{}`",
589597
Segment::names_to_string(&import.module_path),
@@ -601,8 +609,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
601609

602610
match path_res {
603611
PathResult::Module(module) => module,
604-
PathResult::Indeterminate => return false,
605-
PathResult::NonModule(..) | PathResult::Failed { .. } => return true,
612+
PathResult::Indeterminate => return 3,
613+
PathResult::NonModule(..) | PathResult::Failed { .. } => return 0,
606614
}
607615
};
608616

@@ -618,12 +626,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
618626
} => (source, target, source_bindings, target_bindings, type_ns_only),
619627
ImportKind::Glob { .. } => {
620628
self.resolve_glob_import(import);
621-
return true;
629+
return 0;
622630
}
623631
_ => unreachable!(),
624632
};
625633

626-
let mut indeterminate = false;
634+
let mut indeterminate_count = 0;
627635
self.per_ns(|this, ns| {
628636
if !type_ns_only || ns == TypeNS {
629637
if let Err(Undetermined) = source_bindings[ns].get() {
@@ -646,7 +654,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
646654

647655
let parent = import.parent_scope.module;
648656
match source_bindings[ns].get() {
649-
Err(Undetermined) => indeterminate = true,
657+
Err(Undetermined) => indeterminate_count += 1,
650658
// Don't update the resolution, because it was never added.
651659
Err(Determined) if target.name == kw::Underscore => {}
652660
Ok(binding) if binding.is_importable() => {
@@ -670,7 +678,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
670678
}
671679
});
672680

673-
!indeterminate
681+
indeterminate_count
674682
}
675683

676684
/// Performs final import resolution, consistency checks and error reporting.

compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs

+22-6
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,28 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
189189
goal_kind: ty::ClosureKind,
190190
) -> Result<Option<ty::Binder<'tcx, (Ty<'tcx>, Ty<'tcx>)>>, NoSolution> {
191191
match *self_ty.kind() {
192-
ty::FnDef(def_id, substs) => Ok(Some(
193-
tcx.fn_sig(def_id)
194-
.subst(tcx, substs)
195-
.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())),
196-
)),
197-
ty::FnPtr(sig) => Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())))),
192+
// keep this in sync with assemble_fn_pointer_candidates until the old solver is removed.
193+
ty::FnDef(def_id, substs) => {
194+
let sig = tcx.fn_sig(def_id);
195+
if sig.skip_binder().is_fn_trait_compatible()
196+
&& tcx.codegen_fn_attrs(def_id).target_features.is_empty()
197+
{
198+
Ok(Some(
199+
sig.subst(tcx, substs)
200+
.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())),
201+
))
202+
} else {
203+
Err(NoSolution)
204+
}
205+
}
206+
// keep this in sync with assemble_fn_pointer_candidates until the old solver is removed.
207+
ty::FnPtr(sig) => {
208+
if sig.is_fn_trait_compatible() {
209+
Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output()))))
210+
} else {
211+
Err(NoSolution)
212+
}
213+
}
198214
ty::Closure(_, substs) => {
199215
let closure_substs = substs.as_closure();
200216
match closure_substs.kind_ty().to_opt_closure_kind() {

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+1
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ fn suggest_restriction<'tcx>(
420420
) {
421421
if hir_generics.where_clause_span.from_expansion()
422422
|| hir_generics.where_clause_span.desugaring_kind().is_some()
423+
|| projection.map_or(false, |projection| tcx.opt_rpitit_info(projection.def_id).is_some())
423424
{
424425
return;
425426
}

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+10-20
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use rustc_infer::traits::ObligationCause;
1111
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
1212
use rustc_middle::ty::fast_reject::TreatProjections;
1313
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
14-
use rustc_target::spec::abi::Abi;
1514

1615
use crate::traits;
1716
use crate::traits::query::evaluate_obligation::InferCtxtExt;
@@ -291,6 +290,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
291290
return;
292291
}
293292

293+
// Keep this funtion in sync with extract_tupled_inputs_and_output_from_callable
294+
// until the old solver (and thus this function) is removed.
295+
294296
// Okay to skip binder because what we are inspecting doesn't involve bound regions.
295297
let self_ty = obligation.self_ty().skip_binder();
296298
match *self_ty.kind() {
@@ -299,31 +301,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
299301
candidates.ambiguous = true; // Could wind up being a fn() type.
300302
}
301303
// Provide an impl, but only for suitable `fn` pointers.
302-
ty::FnPtr(_) => {
303-
if let ty::FnSig {
304-
unsafety: hir::Unsafety::Normal,
305-
abi: Abi::Rust,
306-
c_variadic: false,
307-
..
308-
} = self_ty.fn_sig(self.tcx()).skip_binder()
309-
{
304+
ty::FnPtr(sig) => {
305+
if sig.is_fn_trait_compatible() {
310306
candidates.vec.push(FnPointerCandidate { is_const: false });
311307
}
312308
}
313309
// Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
314310
ty::FnDef(def_id, _) => {
315-
if let ty::FnSig {
316-
unsafety: hir::Unsafety::Normal,
317-
abi: Abi::Rust,
318-
c_variadic: false,
319-
..
320-
} = self_ty.fn_sig(self.tcx()).skip_binder()
311+
if self.tcx().fn_sig(def_id).skip_binder().is_fn_trait_compatible()
312+
&& self.tcx().codegen_fn_attrs(def_id).target_features.is_empty()
321313
{
322-
if self.tcx().codegen_fn_attrs(def_id).target_features.is_empty() {
323-
candidates
324-
.vec
325-
.push(FnPointerCandidate { is_const: self.tcx().is_const_fn(def_id) });
326-
}
314+
candidates
315+
.vec
316+
.push(FnPointerCandidate { is_const: self.tcx().is_const_fn(def_id) });
327317
}
328318
}
329319
_ => {}

compiler/rustc_trait_selection/src/traits/specialize/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::traits::{
2222
use rustc_data_structures::fx::FxIndexSet;
2323
use rustc_errors::{error_code, DelayDm, Diagnostic};
2424
use rustc_hir::def_id::{DefId, LocalDefId};
25-
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt};
25+
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
2626
use rustc_middle::ty::{InternalSubsts, SubstsRef};
2727
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
2828
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
@@ -350,6 +350,10 @@ fn report_conflicting_impls<'tcx>(
350350
impl_span: Span,
351351
err: &mut Diagnostic,
352352
) {
353+
if (overlap.trait_ref, overlap.self_ty).references_error() {
354+
err.downgrade_to_delayed_bug();
355+
}
356+
353357
match tcx.span_of_impl(overlap.with_impl) {
354358
Ok(span) => {
355359
err.span_label(span, "first implementation here");

0 commit comments

Comments
 (0)