Skip to content

Commit

Permalink
Auto merge of #109453 - matthiaskrgr:rollup-odn02wu, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - #96391 (Windows: make `Command` prefer non-verbatim paths)
 - #108164 (Drop all messages in bounded channel when destroying the last receiver)
 - #108729 (fix: modify the condition that `resolve_imports` stops)
 - #109336 (Constrain const vars to error if const types are mismatched)
 - #109403 (Avoid ICE of attempt to add with overflow in emitter)
 - #109415 (Refactor `handle_missing_lit`.)
 - #109441 (Only implement Fn* traits for extern "Rust" safe function pointers and items)
 - #109446 (Do not suggest bounds restrictions for synthesized RPITITs)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 21, 2023
2 parents 77d50a8 + 94d2028 commit 1db9c06
Show file tree
Hide file tree
Showing 27 changed files with 597 additions and 139 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ impl CodeSuggestion {
});
buf.push_str(&part.snippet);
let cur_hi = sm.lookup_char_pos(part.span.hi());
if cur_hi.line == cur_lo.line {
if cur_hi.line == cur_lo.line && !part.snippet.is_empty() {
// Account for the difference between the width of the current code and the
// snippet being suggested, so that the *later* suggestions are correctly
// aligned on the screen.
Expand Down
17 changes: 13 additions & 4 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,19 @@ impl<'tcx> InferCtxt<'tcx> {
// the expected const's type. Specifically, we don't want const infer vars
// to do any type shapeshifting before and after resolution.
if let Err(guar) = compatible_types {
return Ok(self.tcx.const_error_with_guaranteed(
if relation.a_is_expected() { a.ty() } else { b.ty() },
guar,
));
// HACK: equating both sides with `[const error]` eagerly prevents us
// from leaving unconstrained inference vars during things like impl
// matching in the solver.
let a_error = self.tcx.const_error_with_guaranteed(a.ty(), guar);
if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() {
return self.unify_const_variable(vid, a_error);
}
let b_error = self.tcx.const_error_with_guaranteed(b.ty(), guar);
if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() {
return self.unify_const_variable(vid, b_error);
}

return Ok(if relation.a_is_expected() { a_error } else { b_error });
}

match (a.kind(), b.kind()) {
Expand Down
14 changes: 13 additions & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use rustc_macros::HashStable;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span;
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi;
use rustc_target::spec::abi::{self, Abi};
use std::borrow::Cow;
use std::cmp::Ordering;
use std::fmt;
Expand Down Expand Up @@ -1403,6 +1403,18 @@ impl<'tcx> PolyFnSig<'tcx> {
pub fn abi(&self) -> abi::Abi {
self.skip_binder().abi
}

pub fn is_fn_trait_compatible(&self) -> bool {
matches!(
self.skip_binder(),
ty::FnSig {
unsafety: rustc_hir::Unsafety::Normal,
abi: Abi::Rust,
c_variadic: false,
..
}
)
}
}

pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>;
Expand Down
22 changes: 8 additions & 14 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1843,20 +1843,14 @@ impl<'a> Parser<'a> {
&mut self,
mk_lit_char: impl FnOnce(Symbol, Span) -> L,
) -> PResult<'a, L> {
if let token::Interpolated(inner) = &self.token.kind {
let expr = match inner.as_ref() {
token::NtExpr(expr) => Some(expr),
token::NtLiteral(expr) => Some(expr),
_ => None,
};
if let Some(expr) = expr {
if matches!(expr.kind, ExprKind::Err) {
let mut err = errors::InvalidInterpolatedExpression { span: self.token.span }
.into_diagnostic(&self.sess.span_diagnostic);
err.downgrade_to_delayed_bug();
return Err(err);
}
}
if let token::Interpolated(nt) = &self.token.kind
&& let token::NtExpr(e) | token::NtLiteral(e) = &**nt
&& matches!(e.kind, ExprKind::Err)
{
let mut err = errors::InvalidInterpolatedExpression { span: self.token.span }
.into_diagnostic(&self.sess.span_diagnostic);
err.downgrade_to_delayed_bug();
return Err(err);
}
let token = self.token.clone();
let err = |self_: &Self| {
Expand Down
38 changes: 23 additions & 15 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,13 +423,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// Resolves all imports for the crate. This method performs the fixed-
/// point iteration.
pub(crate) fn resolve_imports(&mut self) {
let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1;
while self.indeterminate_imports.len() < prev_num_indeterminates {
prev_num_indeterminates = self.indeterminate_imports.len();
let mut prev_indeterminate_count = usize::MAX;
let mut indeterminate_count = self.indeterminate_imports.len() * 3;
while indeterminate_count < prev_indeterminate_count {
prev_indeterminate_count = indeterminate_count;
indeterminate_count = 0;
for import in mem::take(&mut self.indeterminate_imports) {
match self.resolve_import(&import) {
true => self.determined_imports.push(import),
false => self.indeterminate_imports.push(import),
let import_indeterminate_count = self.resolve_import(&import);
indeterminate_count += import_indeterminate_count;
match import_indeterminate_count {
0 => self.determined_imports.push(import),
_ => self.indeterminate_imports.push(import),
}
}
}
Expand Down Expand Up @@ -581,9 +585,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
diag.emit();
}

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

match path_res {
PathResult::Module(module) => module,
PathResult::Indeterminate => return false,
PathResult::NonModule(..) | PathResult::Failed { .. } => return true,
PathResult::Indeterminate => return 3,
PathResult::NonModule(..) | PathResult::Failed { .. } => return 0,
}
};

Expand All @@ -618,12 +626,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} => (source, target, source_bindings, target_bindings, type_ns_only),
ImportKind::Glob { .. } => {
self.resolve_glob_import(import);
return true;
return 0;
}
_ => unreachable!(),
};

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

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

!indeterminate
indeterminate_count
}

/// Performs final import resolution, consistency checks and error reporting.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,28 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
goal_kind: ty::ClosureKind,
) -> Result<Option<ty::Binder<'tcx, (Ty<'tcx>, Ty<'tcx>)>>, NoSolution> {
match *self_ty.kind() {
ty::FnDef(def_id, substs) => Ok(Some(
tcx.fn_sig(def_id)
.subst(tcx, substs)
.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())),
)),
ty::FnPtr(sig) => Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())))),
// keep this in sync with assemble_fn_pointer_candidates until the old solver is removed.
ty::FnDef(def_id, substs) => {
let sig = tcx.fn_sig(def_id);
if sig.skip_binder().is_fn_trait_compatible()
&& tcx.codegen_fn_attrs(def_id).target_features.is_empty()
{
Ok(Some(
sig.subst(tcx, substs)
.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())),
))
} else {
Err(NoSolution)
}
}
// keep this in sync with assemble_fn_pointer_candidates until the old solver is removed.
ty::FnPtr(sig) => {
if sig.is_fn_trait_compatible() {
Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output()))))
} else {
Err(NoSolution)
}
}
ty::Closure(_, substs) => {
let closure_substs = substs.as_closure();
match closure_substs.kind_ty().to_opt_closure_kind() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ fn suggest_restriction<'tcx>(
) {
if hir_generics.where_clause_span.from_expansion()
|| hir_generics.where_clause_span.desugaring_kind().is_some()
|| projection.map_or(false, |projection| tcx.opt_rpitit_info(projection.def_id).is_some())
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
use rustc_middle::ty::fast_reject::TreatProjections;
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_target::spec::abi::Abi;

use crate::traits;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
Expand Down Expand Up @@ -291,6 +290,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return;
}

// Keep this funtion in sync with extract_tupled_inputs_and_output_from_callable
// until the old solver (and thus this function) is removed.

// Okay to skip binder because what we are inspecting doesn't involve bound regions.
let self_ty = obligation.self_ty().skip_binder();
match *self_ty.kind() {
Expand All @@ -299,31 +301,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates.ambiguous = true; // Could wind up being a fn() type.
}
// Provide an impl, but only for suitable `fn` pointers.
ty::FnPtr(_) => {
if let ty::FnSig {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
c_variadic: false,
..
} = self_ty.fn_sig(self.tcx()).skip_binder()
{
ty::FnPtr(sig) => {
if sig.is_fn_trait_compatible() {
candidates.vec.push(FnPointerCandidate { is_const: false });
}
}
// Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
ty::FnDef(def_id, _) => {
if let ty::FnSig {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
c_variadic: false,
..
} = self_ty.fn_sig(self.tcx()).skip_binder()
if self.tcx().fn_sig(def_id).skip_binder().is_fn_trait_compatible()
&& self.tcx().codegen_fn_attrs(def_id).target_features.is_empty()
{
if self.tcx().codegen_fn_attrs(def_id).target_features.is_empty() {
candidates
.vec
.push(FnPointerCandidate { is_const: self.tcx().is_const_fn(def_id) });
}
candidates
.vec
.push(FnPointerCandidate { is_const: self.tcx().is_const_fn(def_id) });
}
}
_ => {}
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_trait_selection/src/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::traits::{
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{error_code, DelayDm, Diagnostic};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt};
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{InternalSubsts, SubstsRef};
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
Expand Down Expand Up @@ -350,6 +350,10 @@ fn report_conflicting_impls<'tcx>(
impl_span: Span,
err: &mut Diagnostic,
) {
if (overlap.trait_ref, overlap.self_ty).references_error() {
err.downgrade_to_delayed_bug();
}

match tcx.span_of_impl(overlap.with_impl) {
Ok(span) => {
err.span_label(span, "first implementation here");
Expand Down
Loading

0 comments on commit 1db9c06

Please sign in to comment.