about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-11 00:35:36 +0000
committerbors <bors@rust-lang.org>2023-06-11 00:35:36 +0000
commit970058e16b307e1cff01e2ddb084d2e8d14ea8be (patch)
tree8d33cb2cd310d8dcd2bc2ddf27891c2f0c848601 /compiler
parentb8a50010de397df570b38fe67bda435b665e2d86 (diff)
parent46b64aaef097cab420311834eb58b5d05ea408a7 (diff)
downloadrust-970058e16b307e1cff01e2ddb084d2e8d14ea8be.tar.gz
rust-970058e16b307e1cff01e2ddb084d2e8d14ea8be.zip
Auto merge of #112512 - matthiaskrgr:rollup-o2jh1jx, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #112475 (Fix issue for module name when surround the struct literal with parentheses)
 - #112477 (Give more helpful progress messages in `Assemble`)
 - #112484 (Fix ntdll linkage issues on Windows UWP platforms)
 - #112492 (Migrate GUI colors test to original CSS color format)
 - #112493 (iat selection: normalize self ty & completely erase bound vars)
 - #112497 (abs_sub: fix typo 0[-:][+.]0)
 - #112498 (Update links to Rust Reference in diagnostic)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs76
-rw-r--r--compiler/rustc_parse/messages.ftl2
-rw-r--r--compiler/rustc_parse/src/lexer/unescape_error_reporting.rs2
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs25
-rw-r--r--compiler/rustc_span/src/source_map.rs15
5 files changed, 92 insertions, 28 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index a9e8afe434e..1037a49acdf 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -26,10 +26,9 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{walk_generics, Visitor as _};
 use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
-use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
+use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::middle::stability::AllowUnstable;
-use rustc_middle::ty::fold::FnMutDelegate;
 use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
@@ -43,7 +42,10 @@ use rustc_trait_selection::traits::error_reporting::{
     report_object_safety_error, suggestions::NextTypeParamName,
 };
 use rustc_trait_selection::traits::wf::object_region_bounds;
-use rustc_trait_selection::traits::{self, astconv_object_safety_violations, ObligationCtxt};
+use rustc_trait_selection::traits::{
+    self, astconv_object_safety_violations, NormalizeExt, ObligationCtxt,
+};
+use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 
 use smallvec::{smallvec, SmallVec};
 use std::collections::BTreeSet;
@@ -2442,6 +2444,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             return Ok(None);
         }
 
+        if !tcx.features().inherent_associated_types {
+            tcx.sess
+                .delay_span_bug(span, "found inherent assoc type without the feature being gated");
+        }
+
         //
         // Select applicable inherent associated type candidates modulo regions.
         //
@@ -2465,23 +2472,53 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         let mut fulfillment_errors = Vec::new();
         let mut applicable_candidates: Vec<_> = infcx.probe(|_| {
-            let universe = infcx.create_next_universe();
-
             // Regions are not considered during selection.
-            // FIXME(non_lifetime_binders): Here we are "truncating" or "flattening" the universes
-            // of type and const binders. Is that correct in the selection phase? See also #109505.
-            let self_ty = tcx.replace_escaping_bound_vars_uncached(
-                self_ty,
-                FnMutDelegate {
-                    regions: &mut |_| tcx.lifetimes.re_erased,
-                    types: &mut |bv| {
-                        tcx.mk_placeholder(ty::PlaceholderType { universe, bound: bv })
-                    },
-                    consts: &mut |bv, ty| {
-                        tcx.mk_const(ty::PlaceholderConst { universe, bound: bv }, ty)
-                    },
-                },
-            );
+            let self_ty = self_ty
+                .fold_with(&mut BoundVarEraser { tcx, universe: infcx.create_next_universe() });
+
+            struct BoundVarEraser<'tcx> {
+                tcx: TyCtxt<'tcx>,
+                universe: ty::UniverseIndex,
+            }
+
+            // FIXME(non_lifetime_binders): Don't assign the same universe to each placeholder.
+            impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarEraser<'tcx> {
+                fn interner(&self) -> TyCtxt<'tcx> {
+                    self.tcx
+                }
+
+                fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
+                    if r.is_late_bound() { self.tcx.lifetimes.re_erased } else { r }
+                }
+
+                fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
+                    match *ty.kind() {
+                        ty::Bound(_, bv) => self.tcx.mk_placeholder(ty::PlaceholderType {
+                            universe: self.universe,
+                            bound: bv,
+                        }),
+                        _ => ty.super_fold_with(self),
+                    }
+                }
+
+                fn fold_const(
+                    &mut self,
+                    ct: ty::Const<'tcx>,
+                ) -> <TyCtxt<'tcx> as rustc_type_ir::Interner>::Const {
+                    assert!(!ct.ty().has_escaping_bound_vars());
+
+                    match ct.kind() {
+                        ty::ConstKind::Bound(_, bv) => self.tcx.mk_const(
+                            ty::PlaceholderConst { universe: self.universe, bound: bv },
+                            ct.ty(),
+                        ),
+                        _ => ct.super_fold_with(self),
+                    }
+                }
+            }
+
+            let InferOk { value: self_ty, obligations } =
+                infcx.at(&cause, param_env).normalize(self_ty);
 
             candidates
                 .iter()
@@ -2489,6 +2526,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 .filter(|&(impl_, _)| {
                     infcx.probe(|_| {
                         let ocx = ObligationCtxt::new_in_snapshot(&infcx);
+                        ocx.register_obligations(obligations.clone());
 
                         let impl_substs = infcx.fresh_substs_for_item(span, impl_);
                         let impl_ty = tcx.type_of(impl_).subst(tcx, impl_substs);
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 9263394508e..35eec2c8e1b 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -695,7 +695,7 @@ parse_struct_literal_body_without_path =
 
 parse_struct_literal_needing_parens =
     invalid struct literal
-    .suggestion = you might need to surround the struct literal in parentheses
+    .suggestion = you might need to surround the struct literal with parentheses
 
 parse_struct_literal_not_allowed_here = struct literals are not allowed here
     .suggestion = surround the struct literal with parentheses
diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
index eb9625f923a..461a34b67db 100644
--- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
+++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
@@ -158,7 +158,7 @@ pub(crate) fn emit_unescape_error(
 
                 diag.help(
                     "for more information, visit \
-                     <https://static.rust-lang.org/doc/master/reference.html#literals>",
+                     <https://doc.rust-lang.org/reference/tokens.html#literals>",
                 );
             }
             diag.emit();
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index c1454039685..228eff1269f 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -751,13 +751,24 @@ impl<'a> Parser<'a> {
                     tail.could_be_bare_literal = true;
                     if maybe_struct_name.is_ident() && can_be_struct_literal {
                         // Account for `if Example { a: one(), }.is_pos() {}`.
-                        Err(self.sess.create_err(StructLiteralNeedingParens {
-                            span: maybe_struct_name.span.to(expr.span),
-                            sugg: StructLiteralNeedingParensSugg {
-                                before: maybe_struct_name.span.shrink_to_lo(),
-                                after: expr.span.shrink_to_hi(),
-                            },
-                        }))
+                        // expand `before` so that we take care of module path such as:
+                        // `foo::Bar { ... } `
+                        // we expect to suggest `(foo::Bar { ... })` instead of `foo::(Bar { ... })`
+                        let sm = self.sess.source_map();
+                        let before = maybe_struct_name.span.shrink_to_lo();
+                        if let Ok(extend_before) = sm.span_extend_prev_while(before, |t| {
+                            t.is_alphanumeric() || t == ':' || t == '_'
+                        }) {
+                            Err(self.sess.create_err(StructLiteralNeedingParens {
+                                span: maybe_struct_name.span.to(expr.span),
+                                sugg: StructLiteralNeedingParensSugg {
+                                    before: extend_before.shrink_to_lo(),
+                                    after: expr.span.shrink_to_hi(),
+                                },
+                            }))
+                        } else {
+                            return None;
+                        }
                     } else {
                         self.sess.emit_err(StructLiteralBodyWithoutPath {
                             span: expr.span,
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 1824510a974..c53fe084c4d 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -744,6 +744,21 @@ impl SourceMap {
         })
     }
 
+    /// Extends the given `Span` to previous character while the previous character matches the predicate
+    pub fn span_extend_prev_while(
+        &self,
+        span: Span,
+        f: impl Fn(char) -> bool,
+    ) -> Result<Span, SpanSnippetError> {
+        self.span_to_source(span, |s, start, _end| {
+            let n = s[..start]
+                .char_indices()
+                .rfind(|&(_, c)| !f(c))
+                .map_or(start, |(i, _)| start - i - 1);
+            Ok(span.with_lo(span.lo() - BytePos(n as u32)))
+        })
+    }
+
     /// Extends the given `Span` to just before the next occurrence of `c`.
     pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
         if let Ok(next_source) = self.span_to_next_source(sp) {