about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--mk/cfg/x86_64-unknown-openbsd.mk1
-rw-r--r--mk/platform.mk10
-rw-r--r--mk/target.mk2
-rw-r--r--mk/tests.mk7
-rw-r--r--src/doc/book/syntax-index.md2
-rw-r--r--src/librustc_resolve/lib.rs78
-rw-r--r--src/test/compile-fail/suggest-path-instead-of-mod-dot-item.rs60
-rw-r--r--src/test/run-make/tools.mk6
8 files changed, 139 insertions, 27 deletions
diff --git a/mk/cfg/x86_64-unknown-openbsd.mk b/mk/cfg/x86_64-unknown-openbsd.mk
index 261616ecf1f..e6f28482284 100644
--- a/mk/cfg/x86_64-unknown-openbsd.mk
+++ b/mk/cfg/x86_64-unknown-openbsd.mk
@@ -20,3 +20,4 @@ CFG_LDPATH_x86_64-unknown-openbsd :=
 CFG_RUN_x86_64-unknown-openbsd=$(2)
 CFG_RUN_TARG_x86_64-unknown-openbsd=$(call CFG_RUN_x86_64-unknown-openbsd,,$(2))
 CFG_GNU_TRIPLE_x86_64-unknown-openbsd := x86_64-unknown-openbsd
+RUSTC_FLAGS_x86_64-unknown-openbsd=-C linker=$(call FIND_COMPILER,$(CC))
diff --git a/mk/platform.mk b/mk/platform.mk
index fd8416e8a6e..04cab379de3 100644
--- a/mk/platform.mk
+++ b/mk/platform.mk
@@ -215,16 +215,6 @@ define CFG_MAKE_TOOLCHAIN
 
   ifeq ($$(findstring $(HOST_$(1)),arm aarch64 mips mipsel powerpc),)
 
-  # On OpenBSD, we need to pass the path of libstdc++.so to the linker
-  # (use path of libstdc++.a which is a known name for the same path)
-  ifeq ($(OSTYPE_$(1)),unknown-openbsd)
-    STDCPP_LIBDIR_RUSTFLAGS_$(1)= \
-        -L "$$(dir $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
-        -print-file-name=lib$(CFG_STDCPP_NAME).a))"
-  else
-    STDCPP_LIBDIR_RUSTFLAGS_$(1)=
-  endif
-
   # On Bitrig, we need the relocation model to be PIC for everything
   ifeq (,$(filter $(OSTYPE_$(1)),bitrig))
     LLVM_MC_RELOCATION_MODEL="pic"
diff --git a/mk/target.mk b/mk/target.mk
index 9d5e633c3c6..f90b09479c9 100644
--- a/mk/target.mk
+++ b/mk/target.mk
@@ -95,7 +95,6 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
 		$$(RUSTFLAGS_$(4)) \
 		$$(RUSTFLAGS$(1)_$(4)) \
 		$$(RUSTFLAGS$(1)_$(4)_T_$(2)) \
-		$$(STDCPP_LIBDIR_RUSTFLAGS_$(2)) \
 		--out-dir $$(@D) \
 		-C extra-filename=-$$(CFG_FILENAME_EXTRA) \
 		$$<
@@ -130,7 +129,6 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \
 		| $$(TBIN$(1)_T_$(2)_H_$(3))/
 	@$$(call E, rustc: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) \
-		$$(STDCPP_LIBDIR_RUSTFLAGS_$(2)) \
 		$$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \
 		-o $$@ $$< --cfg $(4)
 
diff --git a/mk/tests.mk b/mk/tests.mk
index bd7414a3bb6..0f30ff8711e 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -393,8 +393,7 @@ $(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): \
 	    $$(subst @,,$$(STAGE$(1)_T_$(2)_H_$(3))) -o $$@ $$< --test \
 		-L "$$(RT_OUTPUT_DIR_$(2))" \
 		$$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \
-		$$(RUSTFLAGS_$(4)) \
-		$$(STDCPP_LIBDIR_RUSTFLAGS_$(2))
+		$$(RUSTFLAGS_$(4))
 
 endef
 
@@ -664,9 +663,9 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) := \
         --android-cross-path=$(CFG_ANDROID_CROSS_PATH) \
         --adb-path=$(CFG_ADB) \
         --adb-test-dir=$(CFG_ADB_TEST_DIR) \
-        --host-rustcflags "$(RUSTC_FLAGS_$(3)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(3)) $$(STDCPP_LIBDIR_RUSTFLAGS_$(3))" \
+        --host-rustcflags "$(RUSTC_FLAGS_$(3)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(3))" \
         --lldb-python-dir=$(CFG_LLDB_PYTHON_DIR) \
-        --target-rustcflags "$(RUSTC_FLAGS_$(2)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(2)) $$(STDCPP_LIBDIR_RUSTFLAGS_$(2))" \
+        --target-rustcflags "$(RUSTC_FLAGS_$(2)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(2))" \
         $$(CTEST_TESTARGS)
 
 ifdef CFG_VALGRIND_RPASS
diff --git a/src/doc/book/syntax-index.md b/src/doc/book/syntax-index.md
index 528c0b537f3..01f06f718f8 100644
--- a/src/doc/book/syntax-index.md
+++ b/src/doc/book/syntax-index.md
@@ -234,5 +234,5 @@
 [Traits (Multiple Trait Bounds)]: traits.html#multiple-trait-bounds
 [Traits]: traits.html
 [Unsafe]: unsafe.html
-[Unsized Types (`?Sized`)]: unsized-types.html#?sized
+[Unsized Types (`?Sized`)]: unsized-types.html#sized
 [Variable Bindings]: variable-bindings.html
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 6896e8e5340..3f7327e700b 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -179,7 +179,7 @@ pub enum ResolutionError<'a> {
     /// error E0424: `self` is not available in a static method
     SelfNotAvailableInStaticMethod,
     /// error E0425: unresolved name
-    UnresolvedName(&'a str, &'a str),
+    UnresolvedName(&'a str, &'a str, UnresolvedNameContext),
     /// error E0426: use of undeclared label
     UndeclaredLabel(&'a str),
     /// error E0427: cannot use `ref` binding mode with ...
@@ -202,6 +202,21 @@ pub enum ResolutionError<'a> {
     AttemptToUseNonConstantValueInConstant,
 }
 
+/// Context of where `ResolutionError::UnresolvedName` arose.
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub enum UnresolvedNameContext {
+    /// `PathIsMod(id)` indicates that a given path, used in
+    /// expression context, actually resolved to a module rather than
+    /// a value. The `id` attached to the variant is the node id of
+    /// the erroneous path expression.
+    PathIsMod(ast::NodeId),
+
+    /// `Other` means we have no extra information about the context
+    /// of the unresolved name error. (Maybe we could eliminate all
+    /// such cases; but for now, this is an information-free default.)
+    Other,
+}
+
 fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
                                        span: syntax::codemap::Span,
                                        resolution_error: ResolutionError<'b>) {
@@ -402,13 +417,46 @@ fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
                       "`self` is not available in a static method. Maybe a `self` argument is \
                        missing?");
         }
-        ResolutionError::UnresolvedName(path, name) => {
+        ResolutionError::UnresolvedName(path, msg, context) => {
             span_err!(resolver.session,
                       span,
                       E0425,
                       "unresolved name `{}`{}",
                       path,
-                      name);
+                      msg);
+
+            match context {
+                UnresolvedNameContext::Other => {} // no help available
+                UnresolvedNameContext::PathIsMod(id) => {
+                    let mut help_msg = String::new();
+                    let parent_id = resolver.ast_map.get_parent_node(id);
+                    if let Some(hir_map::Node::NodeExpr(e)) = resolver.ast_map.find(parent_id) {
+                        match e.node {
+                            ExprField(_, ident) => {
+                                help_msg = format!("To reference an item from the \
+                                                    `{module}` module, use \
+                                                    `{module}::{ident}`",
+                                                   module = &*path,
+                                                   ident = ident.node);
+                            }
+
+                            ExprMethodCall(ident, _, _) => {
+                                help_msg = format!("To call a function from the \
+                                                    `{module}` module, use \
+                                                    `{module}::{ident}(..)`",
+                                                   module = &*path,
+                                                   ident = ident.node);
+                            }
+
+                            _ => {} // no help available
+                        }
+                    }
+
+                    if !help_msg.is_empty() {
+                        resolver.session.fileline_help(span, &help_msg);
+                    }
+                }
+            }
         }
         ResolutionError::UndeclaredLabel(name) => {
             span_err!(resolver.session,
@@ -3539,13 +3587,33 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                         format!("to call `{}::{}`", path_str, path_name),
                                 };
 
+                                let mut context =  UnresolvedNameContext::Other;
                                 if !msg.is_empty() {
-                                    msg = format!(". Did you mean {}?", msg)
+                                    msg = format!(". Did you mean {}?", msg);
+                                } else {
+                                    // we check if this a module and if so, we display a help
+                                    // message
+                                    let name_path = path.segments.iter()
+                                                        .map(|seg| seg.identifier.name)
+                                                        .collect::<Vec<_>>();
+                                    let current_module = self.current_module.clone();
+
+                                    match self.resolve_module_path(current_module,
+                                                   &name_path[..],
+                                                   UseLexicalScope,
+                                                   expr.span,
+                                                   PathSearch) {
+                                        Success(_) => {
+                                            context = UnresolvedNameContext::PathIsMod(expr.id);
+                                        },
+                                        _ => {},
+                                    };
                                 }
 
                                 resolve_error(self,
                                               expr.span,
-                                              ResolutionError::UnresolvedName(&*path_name, &*msg));
+                                              ResolutionError::UnresolvedName(
+                                                  &*path_name, &*msg, context));
                             }
                         }
                     }
diff --git a/src/test/compile-fail/suggest-path-instead-of-mod-dot-item.rs b/src/test/compile-fail/suggest-path-instead-of-mod-dot-item.rs
new file mode 100644
index 00000000000..ecf17fa84d7
--- /dev/null
+++ b/src/test/compile-fail/suggest-path-instead-of-mod-dot-item.rs
@@ -0,0 +1,60 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Beginners write `mod.item` when they should write `mod::item`.
+// This tests that we suggest the latter when we encounter the former.
+
+pub mod a {
+    pub const I: i32 = 1;
+
+    pub fn f() -> i32 { 2 }
+
+    pub mod b {
+        pub const J: i32 = 3;
+
+        pub fn g() -> i32 { 4 }
+    }
+}
+
+fn h1() -> i32 {
+    a.I
+        //~^ ERROR E0425
+        //~| HELP To reference an item from the `a` module, use `a::I`
+}
+
+fn h2() -> i32 {
+    a.g()
+        //~^ ERROR E0425
+        //~| HELP To call a function from the `a` module, use `a::g(..)`
+}
+
+fn h3() -> i32 {
+    a.b.J
+        //~^ ERROR E0425
+        //~| HELP To reference an item from the `a` module, use `a::b`
+}
+
+fn h4() -> i32 {
+    a::b.J
+        //~^ ERROR E0425
+        //~| HELP To reference an item from the `a::b` module, use `a::b::J`
+}
+
+fn h5() -> i32 {
+    a.b.f()
+        //~^ ERROR E0425
+        //~| HELP To reference an item from the `a` module, use `a::b`
+}
+
+fn h6() -> i32 {
+    a::b.f()
+        //~^ ERROR E0425
+        //~| HELP To call a function from the `a::b` module, use `a::b::f(..)`
+}
diff --git a/src/test/run-make/tools.mk b/src/test/run-make/tools.mk
index 88cf2a2b031..efaf1197fbd 100644
--- a/src/test/run-make/tools.mk
+++ b/src/test/run-make/tools.mk
@@ -85,11 +85,7 @@ ifeq ($(UNAME),Bitrig)
 else
 ifeq ($(UNAME),OpenBSD)
 	EXTRACFLAGS := -lm -lpthread
-	# extend search lib for found estdc++ if build using gcc from
-	# ports under OpenBSD. This is needed for:
-	#  - run-make/execution-engine
-	#  - run-make/issue-19371
-	RUSTC := $(RUSTC) -L/usr/local/lib
+	RUSTC := $(RUSTC) -C linker="$(word 1,$(CC:ccache=))"
 else
 	EXTRACFLAGS := -lm -lrt -ldl -lpthread
 	EXTRACXXFLAGS := -lstdc++