提交 ef71df10 编写于 作者: B bors

Auto merge of #71600 - Dylan-DPC:rollup-7tvzi9n, r=Dylan-DPC

Rollup of 6 pull requests

Successful merges:

 - #68716 (Stabilize `Span::mixed_site`)
 - #71263 (Remove unused abs_path method from rustc_span::source_map::FileLoader)
 - #71409 (Point at the return type on `.into()` failure caused by `?`)
 - #71419 (add message for resolution failure because wrong namespace)
 - #71438 (Tweak some suggestions in `rustc_resolve`)
 - #71589 (remove Unique::from for shared pointer types)

Failed merges:

r? @ghost
......@@ -131,7 +131,7 @@ fn from_internal(node: Box<InternalNode<K, V>>) -> Self {
}
unsafe fn from_ptr(ptr: NonNull<LeafNode<K, V>>) -> Self {
BoxedNode { ptr: Unique::from(ptr) }
BoxedNode { ptr: Unique::new_unchecked(ptr.as_ptr()) }
}
fn as_ptr(&self) -> NonNull<LeafNode<K, V>> {
......
......@@ -151,7 +151,7 @@ fn allocate_in(capacity: usize, init: AllocInit, mut alloc: A) -> Self {
let memory = alloc.alloc(layout, init).unwrap_or_else(|_| handle_alloc_error(layout));
Self {
ptr: memory.ptr.cast().into(),
ptr: unsafe { Unique::new_unchecked(memory.ptr.cast().as_ptr()) },
cap: Self::capacity_from_bytes(memory.size),
alloc,
}
......@@ -469,7 +469,7 @@ fn capacity_from_bytes(excess: usize) -> usize {
}
fn set_memory(&mut self, memory: MemoryBlock) {
self.ptr = memory.ptr.cast().into();
self.ptr = unsafe { Unique::new_unchecked(memory.ptr.cast().as_ptr()) };
self.cap = Self::capacity_from_bytes(memory.size);
}
......
......@@ -3,7 +3,6 @@
use crate::marker::{PhantomData, Unsize};
use crate::mem;
use crate::ops::{CoerceUnsized, DispatchFromDyn};
use crate::ptr::NonNull;
// ignore-tidy-undocumented-unsafe
......@@ -171,19 +170,3 @@ fn from(reference: &mut T) -> Self {
unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
}
}
#[unstable(feature = "ptr_internals", issue = "none")]
impl<T: ?Sized> From<&T> for Unique<T> {
#[inline]
fn from(reference: &T) -> Self {
unsafe { Unique { pointer: reference as *const T, _marker: PhantomData } }
}
}
#[unstable(feature = "ptr_internals", issue = "none")]
impl<T: ?Sized> From<NonNull<T>> for Unique<T> {
#[inline]
fn from(p: NonNull<T>) -> Self {
unsafe { Unique::new_unchecked(p.as_ptr()) }
}
}
......@@ -303,7 +303,7 @@ pub fn call_site() -> Span {
/// definition site (local variables, labels, `$crate`) and sometimes at the macro
/// call site (everything else).
/// The span location is taken from the call-site.
#[unstable(feature = "proc_macro_mixed_site", issue = "65049")]
#[stable(feature = "proc_macro_mixed_site", since = "1.45.0")]
pub fn mixed_site() -> Span {
Span(bridge::client::Span::mixed_site())
}
......
......@@ -383,7 +383,7 @@ fn call_has_self_arg(&self, source: PathSource<'_>) -> Option<(Span, Option<Span
has_self_arg
}
fn followed_by_brace(&self, span: Span) -> (bool, Option<(Span, String)>) {
fn followed_by_brace(&self, span: Span) -> (bool, Option<Span>) {
// HACK(estebank): find a better way to figure out that this was a
// parser issue where a struct literal is being used on an expression
// where a brace being opened means a block is being started. Look
......@@ -406,7 +406,7 @@ fn followed_by_brace(&self, span: Span) -> (bool, Option<(Span, String)>) {
_ => false,
};
// In case this could be a struct literal that needs to be surrounded
// by parenthesis, find the appropriate span.
// by parentheses, find the appropriate span.
let mut i = 0;
let mut closing_brace = None;
loop {
......@@ -414,10 +414,7 @@ fn followed_by_brace(&self, span: Span) -> (bool, Option<(Span, String)>) {
match sm.span_to_snippet(sp) {
Ok(ref snippet) => {
if snippet == "}" {
let sp = span.to(sp);
if let Ok(snippet) = sm.span_to_snippet(sp) {
closing_brace = Some((sp, snippet));
}
closing_brace = Some(span.to(sp));
break;
}
}
......@@ -479,17 +476,23 @@ fn smart_resolve_context_dependent_help(
suggested = path_sep(err, &parent);
}
PathSource::Expr(None) if followed_by_brace => {
if let Some((sp, snippet)) = closing_brace {
err.span_suggestion(
sp,
"surround the struct literal with parenthesis",
format!("({})", snippet),
if let Some(sp) = closing_brace {
err.multipart_suggestion(
"surround the struct literal with parentheses",
vec![
(sp.shrink_to_lo(), "(".to_string()),
(sp.shrink_to_hi(), ")".to_string()),
],
Applicability::MaybeIncorrect,
);
} else {
err.span_label(
span, // Note the parenthesis surrounding the suggestion below
format!("did you mean `({} {{ /* fields */ }})`?", path_str),
span, // Note the parentheses surrounding the suggestion below
format!(
"you might want to surround a struct literal with parentheses: \
`({} {{ /* fields */ }})`?",
path_str
),
);
}
suggested = true;
......@@ -516,10 +519,16 @@ fn smart_resolve_context_dependent_help(
err.note("if you want the `try` keyword, you need to be in the 2018 edition");
}
}
(Res::Def(DefKind::TyAlias, _), PathSource::Trait(_)) => {
(Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => {
err.span_label(span, "type aliases cannot be used as traits");
if nightly_options::is_nightly_build() {
err.note("did you mean to use a trait alias?");
let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \
`type` alias";
if let Some(span) = self.r.definitions.opt_span(def_id) {
err.span_help(span, msg);
} else {
err.help(msg);
}
}
}
(Res::Def(DefKind::Mod, _), PathSource::Expr(Some(parent))) => {
......
......@@ -2066,52 +2066,64 @@ fn resolve_path_with_ribs(
};
}
let binding = if let Some(module) = module {
self.resolve_ident_in_module(
module,
ident,
ns,
parent_scope,
record_used,
path_span,
)
} else if ribs.is_none() || opt_ns.is_none() || opt_ns == Some(MacroNS) {
let scopes = ScopeSet::All(ns, opt_ns.is_none());
self.early_resolve_ident_in_lexical_scope(
ident,
scopes,
parent_scope,
record_used,
record_used,
path_span,
)
} else {
let record_used_id =
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
match self.resolve_ident_in_lexical_scope(
ident,
ns,
parent_scope,
record_used_id,
path_span,
&ribs.unwrap()[ns],
) {
// we found a locally-imported or available item/module
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
// we found a local variable or type param
Some(LexicalScopeBinding::Res(res))
if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) =>
{
record_segment_res(self, res);
return PathResult::NonModule(PartialRes::with_unresolved_segments(
res,
path.len() - 1,
));
enum FindBindingResult<'a> {
Binding(Result<&'a NameBinding<'a>, Determinacy>),
PathResult(PathResult<'a>),
}
let find_binding_in_ns = |this: &mut Self, ns| {
let binding = if let Some(module) = module {
this.resolve_ident_in_module(
module,
ident,
ns,
parent_scope,
record_used,
path_span,
)
} else if ribs.is_none() || opt_ns.is_none() || opt_ns == Some(MacroNS) {
let scopes = ScopeSet::All(ns, opt_ns.is_none());
this.early_resolve_ident_in_lexical_scope(
ident,
scopes,
parent_scope,
record_used,
record_used,
path_span,
)
} else {
let record_used_id = if record_used {
crate_lint.node_id().or(Some(CRATE_NODE_ID))
} else {
None
};
match this.resolve_ident_in_lexical_scope(
ident,
ns,
parent_scope,
record_used_id,
path_span,
&ribs.unwrap()[ns],
) {
// we found a locally-imported or available item/module
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
// we found a local variable or type param
Some(LexicalScopeBinding::Res(res))
if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) =>
{
record_segment_res(this, res);
return FindBindingResult::PathResult(PathResult::NonModule(
PartialRes::with_unresolved_segments(res, path.len() - 1),
));
}
_ => Err(Determinacy::determined(record_used)),
}
_ => Err(Determinacy::determined(record_used)),
}
};
FindBindingResult::Binding(binding)
};
let binding = match find_binding_in_ns(self, ns) {
FindBindingResult::PathResult(x) => return x,
FindBindingResult::Binding(binding) => binding,
};
match binding {
Ok(binding) => {
if i == 1 {
......@@ -2201,7 +2213,33 @@ fn resolve_path_with_ribs(
} else if i == 0 {
(format!("use of undeclared type or module `{}`", ident), None)
} else {
(format!("could not find `{}` in `{}`", ident, path[i - 1].ident), None)
let mut msg =
format!("could not find `{}` in `{}`", ident, path[i - 1].ident);
if ns == TypeNS || ns == ValueNS {
let ns_to_try = if ns == TypeNS { ValueNS } else { TypeNS };
if let FindBindingResult::Binding(Ok(binding)) =
find_binding_in_ns(self, ns_to_try)
{
let mut found = |what| {
msg = format!(
"expected {}, found {} `{}` in `{}`",
ns.descr(),
what,
ident,
path[i - 1].ident
)
};
if binding.module().is_some() {
found("module")
} else {
match binding.res() {
def::Res::<NodeId>::Def(kind, id) => found(kind.descr(id)),
_ => found(ns_to_try.descr()),
}
}
};
}
(msg, None)
};
return PathResult::Failed {
span: ident.span,
......
......@@ -20,7 +20,6 @@
use std::sync::atomic::Ordering;
use log::debug;
use std::env;
use std::fs;
use std::io;
......@@ -64,9 +63,6 @@ pub trait FileLoader {
/// Query the existence of a file.
fn file_exists(&self, path: &Path) -> bool;
/// Returns an absolute path to a file, if possible.
fn abs_path(&self, path: &Path) -> Option<PathBuf>;
/// Read the contents of an UTF-8 file into memory.
fn read_file(&self, path: &Path) -> io::Result<String>;
}
......@@ -79,14 +75,6 @@ fn file_exists(&self, path: &Path) -> bool {
fs::metadata(path).is_ok()
}
fn abs_path(&self, path: &Path) -> Option<PathBuf> {
if path.is_absolute() {
Some(path.to_path_buf())
} else {
env::current_dir().ok().map(|cwd| cwd.join(path))
}
}
fn read_file(&self, path: &Path) -> io::Result<String> {
fs::read_to_string(path)
}
......
......@@ -317,20 +317,30 @@ fn report_selection_error(
.starts_with("std::convert::From<std::option::NoneError");
let should_convert_result_to_option = format!("{}", trait_ref)
.starts_with("<std::option::NoneError as std::convert::From<");
if is_try && is_from && should_convert_option_to_result {
err.span_suggestion_verbose(
span.shrink_to_lo(),
"consider converting the `Option<T>` into a `Result<T, _>` using `Option::ok_or` or `Option::ok_or_else`",
".ok_or_else(|| /* error value */)".to_string(),
Applicability::HasPlaceholders,
);
} else if is_try && is_from && should_convert_result_to_option {
err.span_suggestion_verbose(
span.shrink_to_lo(),
"consider converting the `Result<T, _>` into an `Option<T>` using `Result::ok`",
".ok()".to_string(),
Applicability::MachineApplicable,
);
if is_try && is_from {
if should_convert_option_to_result {
err.span_suggestion_verbose(
span.shrink_to_lo(),
"consider converting the `Option<T>` into a `Result<T, _>` \
using `Option::ok_or` or `Option::ok_or_else`",
".ok_or_else(|| /* error value */)".to_string(),
Applicability::HasPlaceholders,
);
} else if should_convert_result_to_option {
err.span_suggestion_verbose(
span.shrink_to_lo(),
"consider converting the `Result<T, _>` into an `Option<T>` \
using `Result::ok`",
".ok()".to_string(),
Applicability::MachineApplicable,
);
}
if let Some(ret_span) = self.return_type_span(obligation) {
err.span_label(
ret_span,
&format!("expected `{}` because of this", trait_ref.self_ty()),
);
}
}
let explanation =
......
......@@ -84,6 +84,8 @@ fn suggest_semicolon_removal(
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
);
fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span>;
fn suggest_impl_trait(
&self,
err: &mut DiagnosticBuilder<'tcx>,
......@@ -761,6 +763,17 @@ fn suggest_semicolon_removal(
}
}
fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> {
let hir = self.tcx.hir();
let parent_node = hir.get_parent_node(obligation.cause.body_id);
let sig = match hir.find(parent_node) {
Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) => sig,
_ => return None,
};
if let hir::FnRetTy::Return(ret_ty) = sig.decl.output { Some(ret_ty.span) } else { None }
}
/// If all conditions are met to identify a returned `dyn Trait`, suggest using `impl Trait` if
/// applicable and signal that the error has been expanded appropriately and needs to be
/// emitted.
......
......@@ -4,7 +4,11 @@ error[E0404]: expected trait, found type alias `Bar`
LL | impl Bar for Baz { }
| ^^^ type aliases cannot be used as traits
|
= note: did you mean to use a trait alias?
help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias
--> $DIR/two_files_data.rs:5:1
|
LL | type Bar = dyn Foo;
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
......
......@@ -45,9 +45,12 @@ error[E0423]: expected value, found struct `T`
--> $DIR/E0423.rs:14:8
|
LL | if T {} == T {} { println!("Ok"); }
| ^---
| |
| help: surround the struct literal with parenthesis: `(T {})`
| ^
|
help: surround the struct literal with parentheses
|
LL | if (T {}) == T {} { println!("Ok"); }
| ^ ^
error: aborting due to 5 previous errors
......
error[E0277]: `?` couldn't convert the error to `()`
--> $DIR/issue-32709.rs:4:11
|
LL | fn a() -> Result<i32, ()> {
| --------------- expected `()` because of this
LL | Err(5)?;
| ^ the trait `std::convert::From<{integer}>` is not implemented for `()`
|
......
use std::sync::mpsc;
fn main() {
let (tx, rx) = mpsc::channel::new(1);
//~^ ERROR expected type, found function `channel` in `mpsc`
}
error[E0433]: failed to resolve: expected type, found function `channel` in `mpsc`
--> $DIR/issue-71406.rs:4:26
|
LL | let (tx, rx) = mpsc::channel::new(1);
| ^^^^^^^ expected type, found function `channel` in `mpsc`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0433`.
error[E0277]: `?` couldn't convert the error to `()`
--> $DIR/option-to-result.rs:5:6
|
LL | fn test_result() -> Result<(),()> {
| ------------- expected `()` because of this
LL | let a:Option<()> = Some(());
LL | a?;
| ^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()`
|
......@@ -14,6 +17,9 @@ LL | a.ok_or_else(|| /* error value */)?;
error[E0277]: `?` couldn't convert the error to `std::option::NoneError`
--> $DIR/option-to-result.rs:11:6
|
LL | fn test_option() -> Option<i32>{
| ----------- expected `std::option::NoneError` because of this
LL | let a:Result<i32, i32> = Ok(5);
LL | a?;
| ^ the trait `std::convert::From<i32>` is not implemented for `std::option::NoneError`
|
......
......@@ -2,7 +2,6 @@
// no-prefer-dynamic
#![feature(proc_macro_hygiene)]
#![feature(proc_macro_mixed_site)]
#![feature(proc_macro_quote)]
#![crate_type = "proc-macro"]
......
......@@ -4,7 +4,11 @@ error[E0404]: expected trait, found type alias `Foo`
LL | impl Foo for S {
| ^^^ type aliases cannot be used as traits
|
= note: did you mean to use a trait alias?
help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias
--> $DIR/issue-3907.rs:5:1
|
LL | type Foo = dyn issue_3907::Foo;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: possible better candidate is found in another module, you can import it into scope
|
LL | use issue_3907::Foo;
......
......@@ -16,7 +16,11 @@ LL | impl K for isize {}
| type aliases cannot be used as traits
| help: a trait with a similar name exists: `I`
|
= note: did you mean to use a trait alias?
help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias
--> $DIR/issue-5035.rs:2:1
|
LL | type K = dyn I;
| ^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
......
......@@ -10,7 +10,11 @@ error[E0404]: expected trait, found type alias `Typedef`
LL | fn g<F:Typedef(isize) -> isize>(x: F) {}
| ^^^^^^^^^^^^^^^^^^^^^^^ type aliases cannot be used as traits
|
= note: did you mean to use a trait alias?
help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias
--> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:4:1
|
LL | type Typedef = isize;
| ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
......
......@@ -46,9 +46,12 @@ error[E0423]: expected value, found struct variant `E::V`
--> $DIR/struct-literal-variant-in-if.rs:10:13
|
LL | if x == E::V { field } {}
| ^^^^----------
| |
| help: surround the struct literal with parenthesis: `(E::V { field })`
| ^^^^
|
help: surround the struct literal with parentheses
|
LL | if x == (E::V { field }) {}
| ^ ^
error[E0308]: mismatched types
--> $DIR/struct-literal-variant-in-if.rs:10:20
......
error[E0277]: `?` couldn't convert the error to `()`
--> $DIR/try-on-option.rs:7:6
|
LL | fn foo() -> Result<u32, ()> {
| --------------- expected `()` because of this
LL | let x: Option<u32> = None;
LL | x?;
| ^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()`
|
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册