about summary refs log tree commit diff
path: root/src/librustc
diff options
context:
space:
mode:
authorBaoshan <pangbw@gmail.com>2019-09-05 22:42:04 -0700
committerGitHub <noreply@github.com>2019-09-05 22:42:04 -0700
commit414d1047291348b5b8bf49e1d76fec978238d89f (patch)
tree7894264d7d7758bbfe15952b598cabd05da75911 /src/librustc
parent109e16e8574a4fc47bf7c1d26b6000731002bc34 (diff)
parent618768492f0c731fcb770dc2d178abe840846419 (diff)
downloadrust-414d1047291348b5b8bf49e1d76fec978238d89f.tar.gz
rust-414d1047291348b5b8bf49e1d76fec978238d89f.zip
Merge pull request #17 from rust-lang/master
sync with rust-lang/rust master branch
Diffstat (limited to 'src/librustc')
-rw-r--r--src/librustc/Cargo.toml2
-rw-r--r--src/librustc/error_codes.rs2
-rw-r--r--src/librustc/hir/map/collector.rs2
-rw-r--r--src/librustc/ich/impls_syntax.rs23
-rw-r--r--src/librustc/infer/error_reporting/mod.rs13
-rw-r--r--src/librustc/lint/context.rs4
-rw-r--r--src/librustc/lint/levels.rs2
-rw-r--r--src/librustc/mir/mod.rs25
-rw-r--r--src/librustc/traits/error_reporting.rs5
-rw-r--r--src/librustc/traits/object_safety.rs72
-rw-r--r--src/librustc/traits/on_unimplemented.rs19
-rw-r--r--src/librustc/ty/mod.rs6
-rw-r--r--src/librustc/ty/util.rs6
13 files changed, 105 insertions, 76 deletions
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index 0222a3dde7a..a479fabafc0 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -21,7 +21,7 @@ scoped-tls = "1.0"
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
 rustc-rayon = "0.2.0"
 rustc-rayon-core = "0.2.0"
-polonius-engine  = "0.9.0"
+polonius-engine  = "0.10.0"
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_target = { path = "../librustc_target" }
 rustc_macros = { path = "../librustc_macros" }
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index 2d09013f675..937a9ea6c1b 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -39,7 +39,7 @@ Generally, `Self: Sized` is used to indicate that the trait should not be used
 as a trait object. If the trait comes from your own crate, consider removing
 this restriction.
 
-### Method references the `Self` type in its arguments or return type
+### Method references the `Self` type in its parameters or return type
 
 This happens when a trait has a method like the following:
 
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 773bb8dde06..b8bd1d73fc2 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -186,7 +186,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
             });
 
         let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| {
-            let name = cstore.crate_name_untracked(cnum).as_str();
+            let name = cstore.crate_name_untracked(cnum).as_interned_str();
             let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
             let hash = cstore.crate_hash_untracked(cnum);
             (name, disambiguator, hash)
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 05e2c7854b4..ddfca3a4cfb 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -9,7 +9,7 @@ use std::mem;
 use syntax::ast;
 use syntax::feature_gate;
 use syntax::parse::token;
-use syntax::symbol::{InternedString, LocalInternedString};
+use syntax::symbol::InternedString;
 use syntax::tokenstream;
 use syntax_pos::SourceFile;
 
@@ -39,27 +39,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString {
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let s: &str = &**self;
-        s.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
-    type KeyType = LocalInternedString;
-
-    #[inline]
-    fn to_stable_hash_key(&self,
-                          _: &StableHashingContext<'a>)
-                          -> LocalInternedString {
-        self.clone()
-    }
-}
-
 impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
     #[inline]
     fn hash_stable<W: StableHasherResult>(&self,
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index e684ccfeeb7..5883be6e268 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1136,12 +1136,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         if let Some((expected, found)) = expected_found {
             match (terr, is_simple_error, expected == found) {
                 (&TypeError::Sorts(ref values), false, true) => {
+                    let sort_string = | a_type: Ty<'tcx> |
+                        if let ty::Opaque(def_id, _) = a_type.sty {
+                            format!(" (opaque type at {})", self.tcx.sess.source_map()
+                                .mk_substr_filename(self.tcx.def_span(def_id)))
+                        } else {
+                            format!(" ({})", a_type.sort_string(self.tcx))
+                        };
                     diag.note_expected_found_extra(
                         &"type",
                         expected,
                         found,
-                        &format!(" ({})", values.expected.sort_string(self.tcx)),
-                        &format!(" ({})", values.found.sort_string(self.tcx)),
+                        &sort_string(values.expected),
+                        &sort_string(values.found),
                     );
                 }
                 (_, false, _) => {
@@ -1627,7 +1634,7 @@ impl<'tcx> ObligationCause<'tcx> {
             MainFunctionType => Error0580("main function has wrong type"),
             StartFunctionType => Error0308("start function has wrong type"),
             IntrinsicType => Error0308("intrinsic has wrong type"),
-            MethodReceiver => Error0308("mismatched method receiver"),
+            MethodReceiver => Error0308("mismatched `self` parameter type"),
 
             // In the case where we have no more specific thing to
             // say, also take a look at the error code, maybe we can
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index affda256322..77df93080cd 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -33,7 +33,7 @@ use crate::util::common::time;
 use std::default::Default as StdDefault;
 use syntax::ast;
 use syntax::edition;
-use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
+use syntax_pos::{MultiSpan, Span, symbol::Symbol};
 use errors::DiagnosticBuilder;
 use crate::hir;
 use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -405,7 +405,7 @@ impl LintStore {
     pub fn check_lint_name(
         &self,
         lint_name: &str,
-        tool_name: Option<LocalInternedString>,
+        tool_name: Option<Symbol>,
     ) -> CheckLintNameResult<'_> {
         let complete_name = if let Some(tool_name) = tool_name {
             format!("{}::{}", tool_name, lint_name)
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 139f4343117..cbc6dbdba7e 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -291,7 +291,7 @@ impl<'a> LintLevelsBuilder<'a> {
                         continue;
                     }
 
-                    Some(tool_ident.as_str())
+                    Some(tool_ident.name)
                 } else {
                     None
                 };
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 5ac99ba1470..8956cbb2bae 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1808,6 +1808,23 @@ pub enum ProjectionElem<V, T> {
     Downcast(Option<Symbol>, VariantIdx),
 }
 
+impl<V, T> ProjectionElem<V, T> {
+    /// Returns `true` if the target of this projection may refer to a different region of memory
+    /// than the base.
+    fn is_indirect(&self) -> bool {
+        match self {
+            Self::Deref => true,
+
+            | Self::Field(_, _)
+            | Self::Index(_)
+            | Self::ConstantIndex { .. }
+            | Self::Subslice { .. }
+            | Self::Downcast(_, _)
+            => false
+        }
+    }
+}
+
 /// Alias for projections as they appear in places, where the base is a place
 /// and the index is a local.
 pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
@@ -1869,6 +1886,14 @@ impl<'tcx> Place<'tcx> {
         }
     }
 
+    /// Returns `true` if this `Place` contains a `Deref` projection.
+    ///
+    /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
+    /// same region of memory as its base.
+    pub fn is_indirect(&self) -> bool {
+        self.iterate(|_, mut projections| projections.any(|proj| proj.elem.is_indirect()))
+    }
+
     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
     /// a single deref of a local.
     //
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index b38e1f5f839..03cc00d87e3 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1384,7 +1384,10 @@ impl<'tcx> TyCtxt<'tcx> {
         let mut reported_violations = FxHashSet::default();
         for violation in violations {
             if reported_violations.insert(violation.clone()) {
-                err.note(&violation.error_msg());
+                match violation.span() {
+                    Some(span) => err.span_label(span, violation.error_msg()),
+                    None => err.note(&violation.error_msg()),
+                };
             }
         }
         Some(err)
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 7ea7bf0257c..f7f459cd27f 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -20,7 +20,7 @@ use std::borrow::Cow;
 use std::iter::{self};
 use syntax::ast::{self};
 use syntax::symbol::InternedString;
-use syntax_pos::Span;
+use syntax_pos::{Span, DUMMY_SP};
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub enum ObjectSafetyViolation {
@@ -32,10 +32,10 @@ pub enum ObjectSafetyViolation {
     SupertraitSelf,
 
     /// Method has something illegal.
-    Method(ast::Name, MethodViolationCode),
+    Method(ast::Name, MethodViolationCode, Span),
 
     /// Associated const.
-    AssocConst(ast::Name),
+    AssocConst(ast::Name, Span),
 }
 
 impl ObjectSafetyViolation {
@@ -46,22 +46,35 @@ impl ObjectSafetyViolation {
             ObjectSafetyViolation::SupertraitSelf =>
                 "the trait cannot use `Self` as a type parameter \
                  in the supertraits or where-clauses".into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) =>
-                format!("method `{}` has no receiver", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) =>
-                format!("method `{}` references the `Self` type \
-                         in its arguments or return type", name).into(),
-            ObjectSafetyViolation::Method(name,
-                                            MethodViolationCode::WhereClauseReferencesSelf(_)) =>
-                format!("method `{}` references the `Self` type in where clauses", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
+            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) =>
+                format!("associated function `{}` has no `self` parameter", name).into(),
+            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!(
+                "method `{}` references the `Self` type in its parameters or return type",
+                name,
+            ).into(),
+            ObjectSafetyViolation::Method(
+                name,
+                MethodViolationCode::WhereClauseReferencesSelf,
+                _,
+            ) => format!("method `{}` references the `Self` type in where clauses", name).into(),
+            ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) =>
                 format!("method `{}` has generic type parameters", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) =>
-                format!("method `{}`'s receiver cannot be dispatched on", name).into(),
-            ObjectSafetyViolation::AssocConst(name) =>
+            ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) =>
+                format!("method `{}`'s `self` parameter cannot be dispatched on", name).into(),
+            ObjectSafetyViolation::AssocConst(name, _) =>
                 format!("the trait cannot contain associated consts like `{}`", name).into(),
         }
     }
+
+    pub fn span(&self) -> Option<Span> {
+        // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so
+        // diagnostics use a `note` instead of a `span_label`.
+        match *self {
+            ObjectSafetyViolation::AssocConst(_, span) |
+            ObjectSafetyViolation::Method(_, _, span) if span != DUMMY_SP => Some(span),
+            _ => None,
+        }
+    }
 }
 
 /// Reasons a method might not be object-safe.
@@ -74,7 +87,7 @@ pub enum MethodViolationCode {
     ReferencesSelf,
 
     /// e.g., `fn foo(&self) where Self: Clone`
-    WhereClauseReferencesSelf(Span),
+    WhereClauseReferencesSelf,
 
     /// e.g., `fn foo<A>()`
     Generic,
@@ -88,9 +101,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// astconv -- currently, `Self` in supertraits. This is needed
     /// because `object_safety_violations` can't be used during
     /// type collection.
-    pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
-                                            -> Vec<ObjectSafetyViolation>
-    {
+    pub fn astconv_object_safety_violations(
+        self,
+        trait_def_id: DefId,
+    ) -> Vec<ObjectSafetyViolation> {
         debug_assert!(self.generics_of(trait_def_id).has_self);
         let violations = traits::supertrait_def_ids(self, trait_def_id)
             .filter(|&def_id| self.predicates_reference_self(def_id, true))
@@ -128,7 +142,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
 
         match self.virtual_call_violation_for_method(trait_def_id, method) {
-            None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
+            None | Some(MethodViolationCode::WhereClauseReferencesSelf) => true,
             Some(_) => false,
         }
     }
@@ -138,12 +152,15 @@ impl<'tcx> TyCtxt<'tcx> {
         let mut violations: Vec<_> = self.associated_items(trait_def_id)
             .filter(|item| item.kind == ty::AssocKind::Method)
             .filter_map(|item|
-                self.object_safety_violation_for_method(trait_def_id, &item)
-                    .map(|code| ObjectSafetyViolation::Method(item.ident.name, code))
+                self.object_safety_violation_for_method(trait_def_id, &item).map(|code| {
+                    ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span)
+                })
             ).filter(|violation| {
-                if let ObjectSafetyViolation::Method(_,
-                    MethodViolationCode::WhereClauseReferencesSelf(span)) = violation
-                {
+                if let ObjectSafetyViolation::Method(
+                    _,
+                    MethodViolationCode::WhereClauseReferencesSelf,
+                    span,
+                ) = violation {
                     // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
                     // It's also hard to get a use site span, so we use the method definition span.
                     self.lint_node_note(
@@ -169,7 +186,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
         violations.extend(self.associated_items(trait_def_id)
             .filter(|item| item.kind == ty::AssocKind::Const)
-            .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name)));
+            .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)));
 
         debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
                trait_def_id,
@@ -325,8 +342,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 .visit_tys_shallow(|t| {
                     self.contains_illegal_self_type_reference(trait_def_id, t)
                 }) {
-            let span = self.def_span(method.def_id);
-            return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
+            return Some(MethodViolationCode::WhereClauseReferencesSelf);
         }
 
         let receiver_ty = self.liberate_late_bound_regions(
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index 0a42b6b46f2..5a988d9509e 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -9,10 +9,9 @@ use syntax::ast::{MetaItem, NestedMetaItem};
 use syntax::attr;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax_pos::Span;
-use syntax_pos::symbol::LocalInternedString;
 
 #[derive(Clone, Debug)]
-pub struct OnUnimplementedFormatString(LocalInternedString);
+pub struct OnUnimplementedFormatString(Symbol);
 
 #[derive(Debug)]
 pub struct OnUnimplementedDirective {
@@ -89,19 +88,19 @@ impl<'tcx> OnUnimplementedDirective {
             if item.check_name(sym::message) && message.is_none() {
                 if let Some(message_) = item.value_str() {
                     message = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, message_.as_str(), span)?);
+                        tcx, trait_def_id, message_, span)?);
                     continue;
                 }
             } else if item.check_name(sym::label) && label.is_none() {
                 if let Some(label_) = item.value_str() {
                     label = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, label_.as_str(), span)?);
+                        tcx, trait_def_id, label_, span)?);
                     continue;
                 }
             } else if item.check_name(sym::note) && note.is_none() {
                 if let Some(note_) = item.value_str() {
                     note = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, note_.as_str(), span)?);
+                        tcx, trait_def_id, note_, span)?);
                     continue;
                 }
             } else if item.check_name(sym::on) && is_root &&
@@ -154,7 +153,7 @@ impl<'tcx> OnUnimplementedDirective {
                 message: None,
                 subcommands: vec![],
                 label: Some(OnUnimplementedFormatString::try_parse(
-                    tcx, trait_def_id, value.as_str(), attr.span)?),
+                    tcx, trait_def_id, value, attr.span)?),
                 note: None,
             }))
         } else {
@@ -218,7 +217,7 @@ impl<'tcx> OnUnimplementedFormatString {
     fn try_parse(
         tcx: TyCtxt<'tcx>,
         trait_def_id: DefId,
-        from: LocalInternedString,
+        from: Symbol,
         err_sp: Span,
     ) -> Result<Self, ErrorReported> {
         let result = OnUnimplementedFormatString(from);
@@ -234,7 +233,8 @@ impl<'tcx> OnUnimplementedFormatString {
     ) -> Result<(), ErrorReported> {
         let name = tcx.item_name(trait_def_id);
         let generics = tcx.generics_of(trait_def_id);
-        let parser = Parser::new(&self.0, None, vec![], false);
+        let s = self.0.as_str();
+        let parser = Parser::new(&s, None, vec![], false);
         let mut result = Ok(());
         for token in parser {
             match token {
@@ -294,7 +294,8 @@ impl<'tcx> OnUnimplementedFormatString {
         }).collect::<FxHashMap<Symbol, String>>();
         let empty_string = String::new();
 
-        let parser = Parser::new(&self.0, None, vec![], false);
+        let s = self.0.as_str();
+        let parser = Parser::new(&s, None, vec![], false);
         parser.map(|p|
             match p {
                 Piece::String(s) => s,
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 56505c04f0f..2da50f37409 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -46,7 +46,7 @@ use std::ops::Range;
 use syntax::ast::{self, Name, Ident, NodeId};
 use syntax::attr;
 use syntax::ext::hygiene::ExpnId;
-use syntax::symbol::{kw, sym, Symbol, LocalInternedString, InternedString};
+use syntax::symbol::{kw, sym, Symbol, InternedString};
 use syntax_pos::Span;
 
 use smallvec;
@@ -3386,10 +3386,6 @@ impl SymbolName {
             name: InternedString::intern(name)
         }
     }
-
-    pub fn as_str(&self) -> LocalInternedString {
-        self.name.as_str()
-    }
 }
 
 impl fmt::Display for SymbolName {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 7a77418050c..a08c82a0ae8 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -709,8 +709,10 @@ impl<'tcx> TyCtxt<'tcx> {
                 substs: SubstsRef<'tcx>,
             ) -> Option<Ty<'tcx>> {
                 if self.found_recursion {
-                    None
-                } else if self.seen_opaque_tys.insert(def_id) {
+                    return None;
+                }
+                let substs = substs.fold_with(self);
+                if self.seen_opaque_tys.insert(def_id) {
                     let generic_ty = self.tcx.type_of(def_id);
                     let concrete_ty = generic_ty.subst(self.tcx, substs);
                     let expanded_ty = self.fold_ty(concrete_ty);